require
5.008;
our
$VERSION
=
'2.20231031'
;
sub
new {
my
(
$class
,
$args
) =
@_
;
my
$self
= {};
bless
$self
,
$class
;
$self
->{
'string'
} = [];
return
$self
;
}
sub
eol {
my
(
$self
) =
@_
;
return
$self
->{
'eol'
}
if
exists
(
$self
->{
'eol'
} );
return
"\n"
;
}
sub
set_eol {
my
(
$self
,
$eol
) =
@_
;
$self
->{
'eol'
} =
$eol
;
return
$self
;
}
sub
indent {
my
(
$self
) =
@_
;
return
$self
->{
'indent'
}
if
exists
(
$self
->{
'indent'
} );
return
' '
;
}
sub
set_indent {
my
(
$self
,
$indent
) =
@_
;
$self
->{
'indent'
} =
$indent
;
return
$self
;
}
sub
sub_indent {
my
(
$self
) =
@_
;
return
$self
->{
'sub_indent'
}
if
exists
(
$self
->{
'sub_indent'
} );
return
' '
;
}
sub
set_sub_indent {
my
(
$self
,
$indent
) =
@_
;
$self
->{
'sub_indent'
} =
$indent
;
return
$self
;
}
sub
try_fold_at {
my
(
$self
) =
@_
;
return
$self
->{
'try_fold_at'
}
if
exists
(
$self
->{
'try_fold_at'
} );
return
800;
}
sub
set_try_fold_at {
my
(
$self
,
$length
) =
@_
;
$self
->{
'try_fold_at'
} =
$length
;
return
$self
;
}
sub
force_fold_at {
my
(
$self
) =
@_
;
return
$self
->{
'force_fold_at'
}
if
exists
(
$self
->{
'force_fold_at'
} );
return
900;
}
sub
set_force_fold_at {
my
(
$self
,
$length
) =
@_
;
$self
->{
'force_fold_at'
} =
$length
;
return
$self
;
}
sub
string {
my
(
$self
,
$string
) =
@_
;
push
@{
$self
->{
'string'
} }, Mail::AuthenticationResults::Token::String->new_from_value(
$string
);
return
$self
;
}
sub
space {
my
(
$self
,
$string
) =
@_
;
push
@{
$self
->{
'string'
} }, Mail::AuthenticationResults::Token::Space->new_from_value(
$string
);
return
$self
;
}
sub
separator {
my
(
$self
,
$string
) =
@_
;
push
@{
$self
->{
'string'
} }, Mail::AuthenticationResults::Token::Separator->new_from_value(
$string
);
return
$self
;
}
sub
comment {
my
(
$self
,
$string
) =
@_
;
push
@{
$self
->{
'string'
} }, Mail::AuthenticationResults::Token::Comment->new_from_value(
$string
);
return
$self
;
}
sub
assignment {
my
(
$self
,
$string
) =
@_
;
push
@{
$self
->{
'string'
} }, Mail::AuthenticationResults::Token::Assignment->new_from_value(
$string
);
return
$self
;
}
sub
as_string {
my
(
$self
) =
@_
;
my
$string
=
q{}
;
my
$string_length
= 0;
my
$content_added
= 0;
my
$sections
= [];
my
$stack
= [];
my
$last_type
;
foreach
my
$part
( @{
$self
->{
'string'
} } ) {
if
(
$part
->is() eq
'space'
&&
$last_type
ne
'space'
) {
push
@$sections
,
$stack
if
@$stack
;
$stack
= [];
}
push
@$stack
,
$part
;
$last_type
=
$part
->is();
}
push
@$sections
,
$stack
if
@$stack
;
my
$eol
=
$self
->eol();;
my
$indent
=
$self
->indent();
my
$sub_indent
=
$self
->sub_indent();
my
$fold_length
= 0;
SECTION:
while
(
my
$section
=
shift
@$sections
) {
if
(
$section
->[0]->is() eq
'space'
&&
$section
->[0]->value() eq
$eol
) {
$fold_length
= 0;
if
( !
exists
(
$section
->[0]->{
'_folded'
} ) ) {
if
(
$section
->[1]->is() eq
'space'
) {
$indent
=
$section
->[1]->value();
}
}
}
my
$section_string
=
join
(
q{}
,
map
{
$_
->value() }
@$section
);
my
$section_length
=
length
(
$section_string
);
if
(
$fold_length
+
$section_length
>
$self
->try_fold_at() ) {
if
(
$fold_length
> 0 ) {
while
(
$section
->[0]->is() eq
'space'
) {
shift
@$section
;
}
unshift
@$section
, Mail::AuthenticationResults::Token::Space->new_from_value(
$indent
.
$sub_indent
);
unshift
@$section
, Mail::AuthenticationResults::Token::Space->new_from_value(
$eol
);
$section
->[0]->{
'_folded'
} = 1;
unshift
@$sections
,
$section
;
next
SECTION;
}
else
{
my
$first_section
= [];
my
$second_section
= [];
push
@$second_section
, Mail::AuthenticationResults::Token::Space->new_from_value(
$eol
);
push
@$second_section
, Mail::AuthenticationResults::Token::Space->new_from_value(
$indent
.
$sub_indent
);
$second_section
->[0]->{
'_folded'
} = 1;
my
$first_section_length
= 0;
foreach
my
$part
(
@$section
) {
my
$part_length
=
length
$part
->value();
if
(
$part_length
+
$first_section_length
<
$self
->try_fold_at() ) {
push
@$first_section
,
$part
;
$first_section_length
+=
$part_length
;
}
else
{
push
@$second_section
,
$part
;
$first_section_length
=
$self
->try_fold_at() + 1;
}
}
if
( (
grep
{
$_
->is() ne
'space'
}
@$first_section
) &&
(
grep
{
$_
->is() ne
'space'
}
@$second_section
) ) {
unshift
@$sections
,
$second_section
;
unshift
@$sections
,
$first_section
;
next
SECTION;
}
}
}
$string
.=
$section_string
;
$fold_length
+=
$section_length
;
}
return
$string
;
}
1;