File Coverage

blib/lib/BACnet/DataTypes/Choice.pm
Criterion Covered Total %
statement 47 61 77.0
branch 15 22 68.1
condition 3 6 50.0
subroutine 7 7 100.0
pod 0 2 0.0
total 72 98 73.4


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             package BACnet::DataTypes::Choice;
4              
5 27     27   182 use warnings;
  27         54  
  27         1682  
6 27     27   143 use strict;
  27         49  
  27         622  
7              
8 27     27   155 use BACnet::DataTypes::Utils;
  27         45  
  27         2663  
9              
10             require BACnet::DataTypes::BitString;
11             require BACnet::DataTypes::Bool;
12             require BACnet::DataTypes::Date;
13             require BACnet::DataTypes::Double;
14             require BACnet::DataTypes::Enum;
15             require BACnet::DataTypes::Int;
16             require BACnet::DataTypes::Null;
17             require BACnet::DataTypes::ObjectIdentifier;
18             require BACnet::DataTypes::OctetString;
19             require BACnet::DataTypes::Real;
20             require BACnet::DataTypes::SequenceValue;
21             require BACnet::DataTypes::SequenceOfValues;
22             require BACnet::DataTypes::Time;
23             require BACnet::DataTypes::UnsignedInt;
24             require BACnet::DataTypes::CharString;
25             require BACnet::DataTypes::Choice;
26             require BACnet::DataTypes::DataType;
27              
28 27     27   133 use parent 'BACnet::DataTypes::DataType';
  27         46  
  27         143  
29              
30 27     27   1898 use constant { LENGTH => 0x00 };
  27         56  
  27         20613  
31              
32             #choice skeleton
33             #tag => [dt, inner skeleton]
34              
35             sub construct {
36 4     4 0 70 my ( $class, $input_dt, $modified_tag ) = @_;
37              
38 4         14 my $self = {
39             data => '',
40             val => $input_dt,
41             };
42              
43 4 100       10 if ( defined $modified_tag ) {
44 2 50       4 if ( defined $modified_tag ) {
45             $self->{data} .=
46 2         11 BACnet::DataTypes::Utils::_make_head( $modified_tag, 1,
47             BACnet::DataTypes::Utils::OPENING_LVT, 1 );
48             }
49 2         9 $self->{data} .= $self->{val}->{data};
50 2 50       5 if ( defined $modified_tag ) {
51             $self->{data} .=
52 2         5 BACnet::DataTypes::Utils::_make_head( $modified_tag, 1,
53             BACnet::DataTypes::Utils::CLOSING_LVT, 1 );
54             }
55             }
56             else {
57 2         8 $self->{data} = $self->{val}->{data};
58             }
59              
60 4         22 return bless $self, $class;
61             }
62              
63             sub parse {
64 4     4 0 9 my ( $class, $data_in, $skeleton, $wrapped ) = @_;
65              
66 4         13 my $self = bless { data => '', val => undef }, $class;
67              
68 4         8 my $context_tag = undef;
69 4         6 my $head_index = 0;
70              
71 4 100 66     20 if ( defined $wrapped
72             && BACnet::DataTypes::Utils::_is_context_sequence($data_in) )
73             {
74 2         5 $context_tag = BACnet::DataTypes::Utils::_get_head_tag($data_in);
75              
76 2 50       8 if ( $context_tag == -1 ) {
77 0         0 $self->{error} = "Choice: opening context lvt tag parse error";
78 0         0 $self->{data} = $data_in;
79 0         0 return $self;
80             }
81 2         8 $head_index += BACnet::DataTypes::Utils::_get_head_length($data_in);
82             }
83              
84 4 50       11 if ( !defined $skeleton ) {
85 0         0 $self->{val} = BACnet::DataTypes::Utils::_parse_any_dt(
86             substr( $data_in, $head_index ) );
87             }
88             else {
89 4         14 my $tag = BACnet::DataTypes::Utils::_get_head_tag(
90             substr( $data_in, $head_index ) );
91 4         13 for my $bone (@$skeleton) {
92              
93 9 100       31 if ( $bone->{tag} == $tag ) {
94 4         14 $self->{val} = BACnet::DataTypes::Utils::_parse_context_dt(
95             substr( $data_in, $head_index ), $bone );
96             }
97             }
98             }
99              
100 4 50       15 if ( !defined $self->{val} ) {
101 0         0 $self->{error} = "Choice: unknown data type tag";
102 0         0 $self->{data} = $data_in;
103 0         0 return $self;
104             }
105              
106 4 50       9 if ( defined $self->{val}->{error} ) {
107 0         0 my $helper = $self->{val}->{error};
108 0         0 $self->{error} = "Choice: error propagated from ($helper)";
109 0         0 $self->{data} = $data_in;
110 0         0 return $self;
111             }
112              
113 4         8 $head_index += length( $self->{val}->{data} );
114              
115 4 100       10 if ( defined $context_tag ) {
116 2 50 33     6 if (
117             BACnet::DataTypes::Utils::_is_end_of_context_sequence(
118             substr( $data_in, $head_index )
119             )
120             && $context_tag == BACnet::DataTypes::Utils::_get_head_tag(
121             substr( $data_in, $head_index )
122             )
123             )
124             {
125 2         3 $head_index += BACnet::DataTypes::Utils::_get_head_length(
126             substr( $data_in, $head_index ) );
127             }
128             else {
129 0         0 $self->{error} = "Choice: closing context lvt tag parse error";
130 0         0 $self->{data} = $data_in;
131 0         0 return $self;
132             }
133 2         5 $head_index += BACnet::DataTypes::Utils::_get_head_length($data_in);
134             }
135              
136 4         8 $self->{data} = substr( $data_in, 0, $head_index );
137 4         13 return $self;
138             }
139              
140             1;