line  
 stmt  
 bran  
 cond  
 sub  
 pod  
 time  
 code  
 
1 
 
  
 
   
 
 
 
 
 
 
 
 
 
 
 
 package WWW::Codeguard;  
 
2 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
3 
 
2
 
 
 
 
 
  
2
   
 
 
 
49252
 
 use strict;  
 
  
 
2
 
 
 
 
 
 
 
 
 
4
 
    
 
  
 
2
 
 
 
 
 
 
 
 
 
64
 
    
 
4 
 
2
 
 
 
 
 
  
2
   
 
 
 
10
 
 use warnings FATAL => 'all', NONFATAL => 'uninitialized';  
 
  
 
2
 
 
 
 
 
 
 
 
 
3
 
    
 
  
 
2
 
 
 
 
 
 
 
 
 
79
 
    
 
5 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
6 
 
2
 
 
 
 
 
  
2
   
 
 
 
8
 
 use Carp qw(croak);  
 
  
 
2
 
 
 
 
 
 
 
 
 
3
 
    
 
  
 
2
 
 
 
 
 
 
 
 
 
85
 
    
 
7 
 
2
 
 
 
 
 
  
2
   
 
 
 
672
 
 use English qw(-no_match_vars);  
 
  
 
2
 
 
 
 
 
 
 
 
 
3740
 
    
 
  
 
2
 
 
 
 
 
 
 
 
 
9
 
    
 
8 
 
2
 
 
 
 
 
  
2
   
 
 
 
1083
 
 use JSON;  
 
  
 
2
 
 
 
 
 
 
 
 
 
8431
 
    
 
  
 
2
 
 
 
 
 
 
 
 
 
12
 
    
 
9 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
10 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 NAME  
 
11 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
12 
 
 
 
 
 
 
 
 
 
 
 
 
 
 WWW::Codeguard - Perl interface to interact with the Codeguard API  
 
13 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
14 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 VERSION  
 
15 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
16 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Version 0.09  
 
17 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
18 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
19 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
20 
 
 
 
 
 
 
 
 
 
 
 
 
 
 our $VERSION = '0.09';  
 
21 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
22 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 SYNOPSIS  
 
23 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
24 
 
 
 
 
 
 
 
 
 
 
 
 
 
 This module provides you with an perl interface to interact with the Codeguard API. This is really just the base class that returns the proper object to use.  
 
25 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Depending on the params you pass, it will return either the 'Partner' object, or the 'User' object.  
 
26 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
27 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	use WWW::Codeguard;  
 
28 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
29 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	my $partner_api = WWW::Codeguard->new(  
 
30 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		{  
 
31 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			api_url => $api_url,  
 
32 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			partner => {  
 
33 
 
 
 
 
 
 
 
 
 
 
 
 
 
 				partner_key => $partner_key,  
 
34 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			},  
 
35 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		}  
 
36 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	);  
 
37 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
38 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	my $user_api = WWW::Codeguard->new(  
 
39 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		{  
 
40 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			api_url => $api_url,  
 
41 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			user => {  
 
42 
 
 
 
 
 
 
 
 
 
 
 
 
 
 				api_key       => $user_api_key,  
 
43 
 
 
 
 
 
 
 
 
 
 
 
 
 
 				api_secret    => $user_api_secret,  
 
44 
 
 
 
 
 
 
 
 
 
 
 
 
 
 				access_secret => $user_access_secret,  
 
45 
 
 
 
 
 
 
 
 
 
 
 
 
 
 				access_token  => $user_access_token,  
 
46 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			},  
 
47 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		}  
 
48 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	);  
 
49 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
50 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
51 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
52 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 Object Initialization  
 
53 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
54 
 
 
 
 
 
 
 
 
 
 
 
 
 
 B 
 
55 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
56 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	api_url  
 
57 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	partner => $hashref_containing_the_partner_options  
 
58 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	user => $hashref_containing_the_user_options  
 
59 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
60 
 
 
 
 
 
 
 
 
 
 
 
 
 
 If both 'partner' and 'user' options are specified, then you should use it an array context to get back both objects:  
 
61 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
62 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	my ($partner_api, $user_api) = WWW::Codeguard->new(  
 
63 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		{  
 
64 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			api_url => $api_url,  
 
65 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			partner => {  
 
66 
 
 
 
 
 
 
 
 
 
 
 
 
 
 				partner_key => $partner_key,  
 
67 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			},  
 
68 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			user => {  
 
69 
 
 
 
 
 
 
 
 
 
 
 
 
 
 				api_key       => $user_api_key,  
 
70 
 
 
 
 
 
 
 
 
 
 
 
 
 
 				api_secret    => $user_api_secret,  
 
71 
 
 
 
 
 
 
 
 
 
 
 
 
 
 				access_secret => $user_access_secret,  
 
72 
 
 
 
 
 
 
 
 
 
 
 
 
 
 				access_token  => $user_access_token,  
 
73 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			},  
 
74 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		}  
 
75 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	);  
 
76 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
77 
 
 
 
 
 
 
 
 
 
 
 
 
 
 If array context is not specified, then it will only return the partner api object even if both objects were created.  
 
78 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
79 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
80 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
81 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub new {  
 
82 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
83 
 
3
 
 
 
 
 
  
3
   
 
  
0
   
 
6370
 
 	my ($class, $opts) = @_;  
 
84 
 
3
 
  
 50
   
 
  
 33
   
 
 
 
 
 
37
 
 	unless ( $opts and UNIVERSAL::isa($opts, 'HASH') and (exists $opts->{partner} or exists $opts->{user}) ) {  
 
  
 
 
 
 
 
  
 66
   
 
 
 
 
 
 
 
    
 
  
 
 
 
 
 
  
 66
   
 
 
 
 
 
 
 
    
 
85 
 
  
0
   
 
 
 
 
 
 
 
 
 
0
 
 		croak ('Object initialization failed. Invalid params passed to constructor.');  
 
86 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
87 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
88 
 
3
 
 
 
 
 
 
 
 
 
6
 
 	my ($partner_obj, $user_obj);  
 
89 
 
3
 
  
100
   
 
  
 66
   
 
 
 
 
 
18
 
 	if ( exists $opts->{partner} and UNIVERSAL::isa($opts->{partner}, 'HASH') ) {  
 
90 
 
2
 
 
 
 
 
 
 
 
 
386
 
 		require WWW::Codeguard::Partner;  
 
91 
 
2
 
 
 
 
 
 
 
 
 
21
 
 		$partner_obj = WWW::Codeguard::Partner->new($opts->{api_url}, $opts->{partner});  
 
92 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
93 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
94 
 
3
 
  
100
   
 
  
 66
   
 
 
 
 
 
22
 
 	if ( exists $opts->{user} and UNIVERSAL::isa($opts->{user}, 'HASH') ) {  
 
95 
 
2
 
 
 
 
 
 
 
 
 
579
 
 		require WWW::Codeguard::User;  
 
96 
 
2
 
 
 
 
 
 
 
 
 
35
 
 		$user_obj = WWW::Codeguard::User->new($opts->{api_url}, $opts->{user});  
 
97 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
98 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
99 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	# If called in an array content, return both;  
 
100 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	# if not just return which ever one is not undef.  
 
101 
 
3
 
  
100
   
 
  
 66
   
 
 
 
 
 
26
 
 	return wantarray ? ($partner_obj, $user_obj) : $partner_obj || $user_obj;  
 
102 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
103 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
104 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 METHODS  
 
105 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
106 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Partner methods are documented in L   
 
107 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
108 
 
 
 
 
 
 
 
 
 
 
 
 
 
 User methods are documented in L   
 
109 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
110 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
111 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
112 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 get_error  
 
113 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
114 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Returns the current value in $self->{_error}.  
 
115 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
116 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
117 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
118 
 
  
0
   
 
 
 
 
 
  
0
   
 
  
1
   
 
0
 
 sub get_error { shift->{_error}; }  
 
119 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
120 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 get_api_url  
 
121 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
122 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Returns the current value in $self->{api_url}.  
 
123 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
124 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
125 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
126 
 
2
 
 
 
 
 
  
2
   
 
  
1
   
 
1228
 
 sub get_api_url { shift->{api_url}; }  
 
127 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
128 
 
4
 
 
 
 
 
  
4
   
 
  
0
   
 
40
 
 sub VERSION { return $WWW::Codeguard::VERSION; }  
 
129 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
130 
 
 
 
 
 
 
 
 
 
 
 
 
 
 # Internal Methods  
 
131 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
132 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub _do_method {  
 
133 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
134 
 
  
0
   
 
 
 
 
 
  
0
   
 
 
 
 
 
 	my ($self, $name, $params) = @_;  
 
135 
 
  
0
   
 
  
  0
   
 
  
  0
   
 
 
 
 
 
 
 
 	if (defined $params and not UNIVERSAL::isa($params, 'HASH')) {  
 
136 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 		$self->_error('$params passed has to be a HASHREF', 1);  
 
137 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
138 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
139 
 
  
0
   
 
  
  0
   
 
 
 
 
 
 
 
 
 
 	$self->_sanitize_params($name, $params) or  
 
140 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		$self->_error('Failed to sanitize params: "'.$self->get_error.'" - The parameters passed in were: '."\n".$self->_stringify_hash($params), 1);  
 
141 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
142 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 	return $self->_dispatch_request($name, $params);  
 
143 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
144 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
145 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub _dispatch_request {  
 
146 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
147 
 
  
0
   
 
 
 
 
 
  
0
   
 
 
 
 
 
 	my ($self, $action, $params) = @_;  
 
148 
 
  
0
   
 
  
  0
   
 
 
 
 
 
 
 
 
 
 	my $base_url = $self->get_api_url() or  
 
149 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		return $self->_error('Failed to fetch api_url', 1);  
 
150 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
151 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 	my $request      = $self->_create_request($action, $params);  
 
152 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 	my $api_response = $self->{_ua}->request($request);  
 
153 
 
  
0
   
 
  
  0
   
 
 
 
 
 
 
 
 
 
 	if (my $output = $api_response->decoded_content) {  
 
154 
 
  
0
   
 
  
  0
   
 
 
 
 
 
 
 
 
 
 		my $json = eval { decode_json($output); }  
 
  
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
    
 
155 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			or return $self->_error('Invalid API reponse received (unable to decode json): '.$api_response->status_line, 1);  
 
156 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 		return $json;  
 
157 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	} else {  
 
158 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 		return $self->_error('Invalid API reponse received (no json received): '.$api_response->status_line, 1);  
 
159 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
160 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 	return;  
 
161 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
162 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
163 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub _sanitize_params {  
 
164 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
165 
 
  
0
   
 
 
 
 
 
  
0
   
 
 
 
 
 
 	my ($self, $action, $params) = @_;  
 
166 
 
  
0
   
 
  
  0
   
 
 
 
 
 
 
 
 
 
 	my $required_params = $self->_fetch_required_params($action, $params) or return $self->_error( 'Unknown action specified: ' . $action );  
 
167 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 	my $optional_params = $self->_fetch_optional_params($action);  
 
168 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
169 
 
  
0
   
 
  
  0
   
 
 
 
 
 
 
 
 
 
 	if (my $check = _check_params($params, $required_params, $optional_params) ) {  
 
170 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 		my $error;  
 
171 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 		$error .= 'Missing required parameter(s): ' . join (', ', @{ $check->{'required_params'} } ).' ; '  
 
172 
 
  
0
   
 
  
  0
   
 
 
 
 
 
 
 
 
 
 			if $check->{'required_params'};  
 
173 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 		$error .= 'Blank parameter(s): ' . join (', ', @{ $check->{'blank_params'} } ).' ; '  
 
174 
 
  
0
   
 
  
  0
   
 
 
 
 
 
 
 
 
 
 			if $check->{'blank_params'};  
 
175 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 		$self->_error($error);  
 
176 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 		return;  
 
177 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
178 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
179 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 	return 1;  
 
180 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
181 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
182 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub _set_content {  
 
183 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
184 
 
  
0
   
 
 
 
 
 
  
0
   
 
 
 
 
 
 	my ($self, $request, $params) = @_;  
 
185 
 
  
0
   
 
  
  0
   
 
 
 
 
 
 
 
 
 
 	if ('GET' ne $request->method) {  
 
186 
 
  
0
   
 
  
  0
   
 
 
 
 
 
 
 
 
 
 		my $json = eval {  
 
187 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 			encode_json( $params );  
 
188 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		} or $self->_error('Failed to encode json payload for request', 1);  
 
189 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 		$request->content($json);  
 
190 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
191 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 	return;  
 
192 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
193 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
194 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 _check_params  
 
195 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
196 
 
 
 
 
 
 
 
 
 
 
 
 
 
 B 
 
197 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
198 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	1) the hashref to the params that need to be checked.  
 
199 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	2) the hashref to the 'required' set of params  
 
200 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	3) the hashref to the 'optional' set of params  
 
201 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
202 
 
 
 
 
 
 
 
 
 
 
 
 
 
 B: Undef if everything is good. If errors are detected, it will return a hashref that has two arrays:   
 
203 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
204 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	'required_params' - which will list the required params that are missing. And  
 
205 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	'blank_params'    - which will list the params that have blank values specified for them.  
 
206 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
207 
 
 
 
 
 
 
 
 
 
 
 
 
 
 This also 'prunes' the first hashref of params that are not specified in either the required or the optional hashrefs.  
 
208 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
209 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
210 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
211 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub _check_params {  
 
212 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
213 
 
  
0
   
 
 
 
 
 
  
0
   
 
 
 
 
 
 	my ($params_to_check, $required_params, $optional_params) = @_;  
 
214 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 	my $output;  
 
215 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
216 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 	foreach my $param ( keys %{ $params_to_check } ) {  
 
  
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
    
 
217 
 
  
0
   
 
  
  0
   
 
  
  0
   
 
 
 
 
 
 
 
 		if (not (exists $required_params->{$param} or exists $optional_params->{$param} ) ) {  
 
  
 
 
 
  
  0
   
 
 
 
 
 
 
 
 
 
    
 
218 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 			delete $params_to_check->{$param};  
 
219 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		} elsif (not length $params_to_check->{ $param } ) {  
 
220 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 			push @{ $output->{'blank_params'} }, $param;  
 
  
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
    
 
221 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		}  
 
222 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
223 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
224 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 	foreach my $required_param ( keys %{ $required_params } ) {  
 
  
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
    
 
225 
 
  
0
   
 
  
  0
   
 
  
  0
   
 
 
 
 
 
 
 
 		if (not (exists $params_to_check->{ $required_param } and defined $params_to_check->{ $required_param } ) ) {  
 
226 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 			push @{ $output->{'required_params'} }, $required_param;  
 
  
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
    
 
227 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		}  
 
228 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
229 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
230 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 	return $output;  
 
231 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
232 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
233 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub _stringify_hash {  
 
234 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
235 
 
  
0
   
 
 
 
 
 
  
0
   
 
 
 
 
 
 	my $self    = shift;  
 
236 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 	my $hashref = shift;  
 
237 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 	my $string;  
 
238 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 	while (my ($key, $value) = each %{$hashref}) {  
 
  
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
    
 
239 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 		$string .= $key.'='.$value.', ';  
 
240 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
241 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 	$string =~ s/, $//;  
 
242 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 	return $string;  
 
243 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
244 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
245 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 _error  
 
246 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
247 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Internal method that is used to report and set $self->{_error}.  
 
248 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
249 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Will croak if a true second argument is passed. Example:  
 
250 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
251 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	$self->_error($msg, 1);   
 
252 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
253 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
254 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
255 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub _error {  
 
256 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
257 
 
  
0
   
 
 
 
 
 
  
0
   
 
 
 
 
 
 	my ($self, $msg, $croak) = @_;  
 
258 
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
 	$self->{_error} = $msg;  
 
259 
 
  
0
   
 
  
  0
   
 
 
 
 
 
 
 
 
 
 	if ($croak) {  
 
260 
 
0
 
 
 
 
 
 
 
 
 
 
 
 		croak $msg;  
 
261 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
262 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
263 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
264 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 AUTHOR  
 
265 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
266 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Rishwanth Yeddula, C<<  >>   
 
267 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
268 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 COMAINTAINERS  
 
269 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
270 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =over 4  
 
271 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
272 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item David Oswald, C<<  >>   
 
273 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
274 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item James Jacobson, C<<  >>   
 
275 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
276 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =back  
 
277 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
278 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 BUGS  
 
279 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
280 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Please report any bugs or feature requests to C, or through   
 
281 
 
 
 
 
 
 
 
 
 
 
 
 
 
 the web interface at L.  I will be notified, and then you'll   
 
282 
 
 
 
 
 
 
 
 
 
 
 
 
 
 automatically be notified of progress on your bug as I make changes.  
 
283 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
284 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 SUPPORT  
 
285 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
286 
 
 
 
 
 
 
 
 
 
 
 
 
 
 You can find documentation for this module with the following perldoc commands.  
 
287 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
288 
 
 
 
 
 
 
 
 
 
 
 
 
 
     perldoc WWW::Codeguard  
 
289 
 
 
 
 
 
 
 
 
 
 
 
 
 
     perldoc WWW::Codeguard::Partner  
 
290 
 
 
 
 
 
 
 
 
 
 
 
 
 
     perldoc WWW::Codeguard::User  
 
291 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
292 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
293 
 
 
 
 
 
 
 
 
 
 
 
 
 
 You can also look for information at:  
 
294 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
295 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =over 4  
 
296 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
297 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * RT: CPAN's request tracker (report bugs here)  
 
298 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
299 
 
 
 
 
 
 
 
 
 
 
 
 
 
 L   
 
300 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
301 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * AnnoCPAN: Annotated CPAN documentation  
 
302 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
303 
 
 
 
 
 
 
 
 
 
 
 
 
 
 L   
 
304 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
305 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * CPAN Ratings  
 
306 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
307 
 
 
 
 
 
 
 
 
 
 
 
 
 
 L   
 
308 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
309 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * Search CPAN  
 
310 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
311 
 
 
 
 
 
 
 
 
 
 
 
 
 
 L 
 
312 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
313 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =back  
 
314 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
315 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 ACKNOWLEDGMENTS  
 
316 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
317 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Thanks to L 
 
318 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
319 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 LICENSE AND COPYRIGHT  
 
320 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
321 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Copyright 2014 Rishwanth Yeddula.  
 
322 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
323 
 
 
 
 
 
 
 
 
 
 
 
 
 
 This program is free software; you can redistribute it and/or modify it  
 
324 
 
 
 
 
 
 
 
 
 
 
 
 
 
 under the terms of the the Artistic License (2.0). You may obtain a  
 
325 
 
 
 
 
 
 
 
 
 
 
 
 
 
 copy of the full license at:  
 
326 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
327 
 
 
 
 
 
 
 
 
 
 
 
 
 
 L   
 
328 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
329 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Any use, modification, and distribution of the Standard or Modified  
 
330 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Versions is governed by this Artistic License. By using, modifying or  
 
331 
 
 
 
 
 
 
 
 
 
 
 
 
 
 distributing the Package, you accept this license. Do not use, modify,  
 
332 
 
 
 
 
 
 
 
 
 
 
 
 
 
 or distribute the Package, if you do not accept this license.  
 
333 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
334 
 
 
 
 
 
 
 
 
 
 
 
 
 
 If your Modified Version has been derived from a Modified Version made  
 
335 
 
 
 
 
 
 
 
 
 
 
 
 
 
 by someone other than you, you are nevertheless required to ensure that  
 
336 
 
 
 
 
 
 
 
 
 
 
 
 
 
 your Modified Version complies with the requirements of this license.  
 
337 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
338 
 
 
 
 
 
 
 
 
 
 
 
 
 
 This license does not grant you the right to use any trademark, service  
 
339 
 
 
 
 
 
 
 
 
 
 
 
 
 
 mark, tradename, or logo of the Copyright Holder.  
 
340 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
341 
 
 
 
 
 
 
 
 
 
 
 
 
 
 This license includes the non-exclusive, worldwide, free-of-charge  
 
342 
 
 
 
 
 
 
 
 
 
 
 
 
 
 patent license to make, have made, use, offer to sell, sell, import and  
 
343 
 
 
 
 
 
 
 
 
 
 
 
 
 
 otherwise transfer the Package with respect to any patent claims  
 
344 
 
 
 
 
 
 
 
 
 
 
 
 
 
 licensable by the Copyright Holder that are necessarily infringed by the  
 
345 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Package. If you institute patent litigation (including a cross-claim or  
 
346 
 
 
 
 
 
 
 
 
 
 
 
 
 
 counterclaim) against any party alleging that the Package constitutes  
 
347 
 
 
 
 
 
 
 
 
 
 
 
 
 
 direct or contributory patent infringement, then this Artistic License  
 
348 
 
 
 
 
 
 
 
 
 
 
 
 
 
 to you shall terminate on the date that such litigation is filed.  
 
349 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
350 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER  
 
351 
 
 
 
 
 
 
 
 
 
 
 
 
 
 AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.  
 
352 
 
 
 
 
 
 
 
 
 
 
 
 
 
 THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR  
 
353 
 
 
 
 
 
 
 
 
 
 
 
 
 
 PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY  
 
354 
 
 
 
 
 
 
 
 
 
 
 
 
 
 YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR  
 
355 
 
 
 
 
 
 
 
 
 
 
 
 
 
 CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR  
 
356 
 
 
 
 
 
 
 
 
 
 
 
 
 
 CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,  
 
357 
 
 
 
 
 
 
 
 
 
 
 
 
 
 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
 
358 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
359 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
360 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
361 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
362 
 
 
 
 
 
 
 
 
 
 
 
 
 
 1; # End of WWW::Codeguard