line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Protocol::FIX::Message; |
2
|
|
|
|
|
|
|
|
3
|
11
|
|
|
11
|
|
88
|
use strict; |
|
11
|
|
|
|
|
23
|
|
|
11
|
|
|
|
|
333
|
|
4
|
11
|
|
|
11
|
|
56
|
use warnings; |
|
11
|
|
|
|
|
19
|
|
|
11
|
|
|
|
|
318
|
|
5
|
|
|
|
|
|
|
|
6
|
11
|
|
|
11
|
|
57
|
use Protocol::FIX; |
|
11
|
|
|
|
|
31
|
|
|
11
|
|
|
|
|
246
|
|
7
|
|
|
|
|
|
|
|
8
|
11
|
|
|
11
|
|
55
|
use mro; |
|
11
|
|
|
|
|
21
|
|
|
11
|
|
|
|
|
63
|
|
9
|
11
|
|
|
11
|
|
308
|
use parent qw/Protocol::FIX::BaseComposite/; |
|
11
|
|
|
|
|
30
|
|
|
11
|
|
|
|
|
57
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
our $VERSION = '0.06'; ## VERSION |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
=head1 NAME |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
Protocol::FIX::Message - FIX protocol message definition |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
=cut |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
=head1 METHODS |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
=head3 serialize |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
serialize($self, $values) |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
Serializes provided values into string. |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
$message->serialize([ |
28
|
|
|
|
|
|
|
field => 'value', |
29
|
|
|
|
|
|
|
component => [ |
30
|
|
|
|
|
|
|
other_field => 'value-2', |
31
|
|
|
|
|
|
|
group_field => [ |
32
|
|
|
|
|
|
|
[some_field_1 => 'value-3.1.1', some_field_1 => 'value-3.1.2'], |
33
|
|
|
|
|
|
|
[some_field_1 => 'value-3.2.1', some_field_1 => 'value-3.2.2'], |
34
|
|
|
|
|
|
|
], |
35
|
|
|
|
|
|
|
], |
36
|
|
|
|
|
|
|
]); |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
Error will be thrown if values do not conform the specification (e.g. |
39
|
|
|
|
|
|
|
string provided, while integer is expected). |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
The B (BeginString, MsgType, and CheckSum) are calculated and |
42
|
|
|
|
|
|
|
added to serialized string automatically. |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
=cut |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
sub serialize { |
47
|
17
|
|
|
17
|
1
|
4319
|
my ($self, $values) = @_; |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
# the SOH / trailing separator is part of the body, and it is included |
50
|
|
|
|
|
|
|
# in body length and checksum |
51
|
17
|
|
|
|
|
124
|
my $body = join($Protocol::FIX::SEPARATOR, $self->{serialized}->{message_type}, $self->next::method($values), ''); |
52
|
|
|
|
|
|
|
|
53
|
10
|
|
|
|
|
141
|
my $body_length = $self->{managed_composites}->{BodyLength}->serialize(length($body)); |
54
|
|
|
|
|
|
|
|
55
|
10
|
|
|
|
|
43
|
my $header_body = join($Protocol::FIX::SEPARATOR, $self->{serialized}->{begin_string}, $body_length, $body); |
56
|
|
|
|
|
|
|
|
57
|
10
|
|
|
|
|
18
|
my $sum = 0; |
58
|
10
|
|
|
|
|
362
|
$sum += ord $_ for split //, $header_body; |
59
|
10
|
|
|
|
|
65
|
$sum %= 256; |
60
|
10
|
|
|
|
|
147
|
my $checksum = $self->{managed_composites}->{CheckSum}->serialize(sprintf('%03d', $sum)); |
61
|
|
|
|
|
|
|
|
62
|
10
|
|
|
|
|
60
|
return $header_body . join($Protocol::FIX::SEPARATOR, $checksum, ''); |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
=head1 METHODS (for protocol developers) |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=head3 new |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
new($class, $name, $category, $message_type, $composites, $protocol) |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
Creates new Message (performed by Protocol, when it parses XML definition) |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
=cut |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
sub new { |
76
|
655
|
|
|
655
|
1
|
1936
|
my ($class, $name, $category, $message_type, $composites, $protocol) = @_; |
77
|
|
|
|
|
|
|
|
78
|
655
|
|
|
|
|
1742
|
my $message_type_field = $protocol->field_by_name('MsgType'); |
79
|
|
|
|
|
|
|
|
80
|
655
|
|
|
|
|
2452
|
my $message_type_string = $message_type_field->{values}->{by_id}->{$message_type}; |
81
|
655
|
50
|
|
|
|
1498
|
die "specified message type '$message_type' is not available in protocol" |
82
|
|
|
|
|
|
|
unless defined $message_type_string; |
83
|
|
|
|
|
|
|
|
84
|
655
|
|
|
|
|
2186
|
my $serialized_message_type = $message_type_field->serialize($message_type_string); |
85
|
|
|
|
|
|
|
|
86
|
655
|
50
|
33
|
|
|
5274
|
die "message category must be defined" |
87
|
|
|
|
|
|
|
if (!defined($category) || $category !~ /.+/); |
88
|
|
|
|
|
|
|
|
89
|
655
|
|
|
|
|
1103
|
my @all_composites = (@{$protocol->header->{composites}}, @$composites, @{$protocol->trailer->{composites}}); |
|
655
|
|
|
|
|
1882
|
|
|
655
|
|
|
|
|
1675
|
|
90
|
|
|
|
|
|
|
|
91
|
655
|
|
|
|
|
1327
|
my @body_composites; |
92
|
655
|
|
|
|
|
2032
|
for (my $idx = 0; $idx < @all_composites; $idx += 2) { |
93
|
34589
|
|
|
|
|
47338
|
my $c = $all_composites[$idx]; |
94
|
34589
|
100
|
|
|
|
59616
|
next if exists $protocol->managed_composites->{$c->{name}}; |
95
|
|
|
|
|
|
|
|
96
|
31969
|
|
|
|
|
70901
|
push @body_composites, $c, $all_composites[$idx + 1]; |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
|
99
|
655
|
|
|
|
|
3152
|
my $obj = next::method($class, $name, 'message', \@body_composites); |
100
|
|
|
|
|
|
|
|
101
|
655
|
|
|
|
|
1926
|
$obj->{category} = $category; |
102
|
|
|
|
|
|
|
$obj->{serialized} = { |
103
|
|
|
|
|
|
|
begin_string => $protocol->{begin_string}, |
104
|
655
|
|
|
|
|
3513
|
message_type => $serialized_message_type, |
105
|
|
|
|
|
|
|
}; |
106
|
|
|
|
|
|
|
$obj->{managed_composites} = { |
107
|
655
|
|
|
|
|
2423
|
BodyLength => $protocol->field_by_name('BodyLength'), |
108
|
|
|
|
|
|
|
CheckSum => $protocol->field_by_name('CheckSum'), |
109
|
|
|
|
|
|
|
}; |
110
|
|
|
|
|
|
|
|
111
|
655
|
|
|
|
|
8352
|
return $obj; |
112
|
|
|
|
|
|
|
} |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
1; |