summaryrefslogtreecommitdiffabout
path: root/lib/Config/HAProxy/Iterator.pm
blob: 6d80dd9f00f1dc089583768bfa8c901b2b07b433 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package Config::HAProxy::Iterator;
use strict;
use warnings;
use Config::HAProxy::Node;
use Carp;

use constant {
    NO_RECURSION => 0,
    INORDER => 1,
    POSTORDER => 2
};

sub new {
    my $class = shift;
    my $node = shift;
    my $self = bless { }, $class;
    if ($node->is_section) {
	$self->{_list} = [ $node->tree() ];
    } else {
	$self->{_list} = [ $node ];
    }
    local %_ = @_;
    if (defined($_{recursive})) {
	$self->{_recursive} = $_{recursive};
    } elsif ($_{inorder}) {
	$self->{_recursive} = INORDER;
    } elsif ($_{postorder}) {
	$self->{_recursive} = POSTORDER;
    } else {
	$self->{_recursive} = NO_RECURSION;
    }
    return $self;
}

sub recursive  { shift->{_recursive} }
sub inorder  { shift->{_recursive} == INORDER }
sub postorder { shift->{_recursive} == POSTORDER } 

sub next {
    my $self = shift;

    if ($self->{_itr}) {
	if (defined(my $v = $self->{_itr}->next())) {
	    return $v;
	} else {
	    delete $self->{_itr};
	    return $self->{_cur} if $self->postorder;
	}
    }

    if (defined($self->{_cur} = shift @{$self->{_list}})) {
	if ($self->recursive && $self->{_cur}->is_section) {
	    $self->{_itr} = $self->{_cur}->iterator(recursive => $self->recursive);
	    if ($self->inorder) {
		return $self->{_cur};
	    } else {
		return $self->next();
	    }
	}
    }

    return $self->{_cur};
}

1;
__END__
    
=head1 NAME

Config::HAProxy::Iterator - Iterate over objects in the parse tree

=head1 SYNOPSIS

    $cfg = Config::HAProxy->new->parse;    
    $itr = $cfg->iterator(inorder => 1);
    while (defined(my $node = $itr->next)) {
        # Do something with $node
    }

=head1 DESCRIPTION

The iterator object provides a method for iterating over all nodes in the
HAProxy parse tree. The object is returned by the B<iterator> method of
B<Config::HAProxy> and B<Config::HAProxy::Node> objects. The method takes
as optional argument the keyword specifying the order in which the tree nodes
should be traversed. This keyword can be one of the following:

=over 4

=item B<recursive =E<gt> 0>

No recursion. The traversal will not descend into section nodes. This is the
default.    
    
=item B<inorder =E<gt> 1>

The nodes will be traversed in the inorder manner, i.e. the section node
will be visited first, and all its sub-nodes after it.    

=item B<postorder =E<gt> 1>

The nodes will be traversed in the postorder manner, i.e. for each section
node, its sub-nodes will be visited first, and the node itself afterward.

=back

=head1 CONSTRUCTOR

Note: This section is informative. You never need to create
B<Config::HAProxy::Iterator> objects explicitly. Please use the B<iterator>
method of B<Config::HAProxy> or B<Config::HAProxy::Node> class objects.

    $itr = new Config::HAProxy::Iterator($node, %rec);

Returns new iterator object for traversing the tree starting from B<$node>,
which must be a B<Config::HAProxy::Node> object. Optional B<%rec> is one of
the keywords discussed above, in section B<DESCRIPTION>.    
    
=head1 METHODS

=head2 next

    $node = $itr->next;

Returns next node in the traversal sequence. If all nodes were visited, returns
B<undef>.

=head1 SEE ALSO

B<HAProxy::Config>, B<HAProxy::Config::Node>.

=cut    
    

	    

	

Return to:

Send suggestions and report system problems to the System administrator.