1package IO::Lines;
2
3
4=head1 NAME
5
6IO::Lines - IO:: interface for reading/writing an array of lines
7
8
9=head1 SYNOPSIS
10
11    use IO::Lines;
12
13    ### See IO::ScalarArray for details
14
15
16=head1 DESCRIPTION
17
18This class implements objects which behave just like FileHandle
19(or IO::Handle) objects, except that you may use them to write to
20(or read from) an array of lines.  They can be tiehandle'd as well.
21
22This is a subclass of L<IO::ScalarArray|IO::ScalarArray>
23in which the underlying
24array has its data stored in a line-oriented-format: that is,
25every element ends in a C<"\n">, with the possible exception of the
26final element.  This makes C<getline()> I<much> more efficient;
27if you plan to do line-oriented reading/printing, you want this class.
28
29The C<print()> method will enforce this rule, so you can print
30arbitrary data to the line-array: it will break the data at
31newlines appropriately.
32
33See L<IO::ScalarArray> for full usage and warnings.
34
35=cut
36
37use Carp;
38use strict;
39use IO::ScalarArray;
40use vars qw($VERSION @ISA);
41
42# The package version, both in 1.23 style *and* usable by MakeMaker:
43$VERSION = "2.110";
44
45# Inheritance:
46@ISA = qw(IO::ScalarArray);     ### also gets us new_tie  :-)
47
48
49#------------------------------
50#
51# getline
52#
53# Instance method, override.
54# Return the next line, or undef on end of data.
55# Can safely be called in an array context.
56# Currently, lines are delimited by "\n".
57#
58sub getline {
59    my $self = shift;
60
61    if (!defined $/) {
62	return join( '', $self->_getlines_for_newlines );
63    }
64    elsif ($/ eq "\n") {
65	if (!*$self->{Pos}) {      ### full line...
66	    return *$self->{AR}[*$self->{Str}++];
67	}
68	else {                     ### partial line...
69	    my $partial = substr(*$self->{AR}[*$self->{Str}++], *$self->{Pos});
70	    *$self->{Pos} = 0;
71	    return $partial;
72	}
73    }
74    else {
75	croak 'unsupported $/: must be "\n" or undef';
76    }
77}
78
79#------------------------------
80#
81# getlines
82#
83# Instance method, override.
84# Return an array comprised of the remaining lines, or () on end of data.
85# Must be called in an array context.
86# Currently, lines are delimited by "\n".
87#
88sub getlines {
89    my $self = shift;
90    wantarray or croak("can't call getlines in scalar context!");
91
92    if ((defined $/) and ($/ eq "\n")) {
93	return $self->_getlines_for_newlines(@_);
94    }
95    else {         ### slow but steady
96	return $self->SUPER::getlines(@_);
97    }
98}
99
100#------------------------------
101#
102# _getlines_for_newlines
103#
104# Instance method, private.
105# If $/ is newline, do fast getlines.
106# This CAN NOT invoke getline!
107#
108sub _getlines_for_newlines {
109    my $self = shift;
110    my ($rArray, $Str, $Pos) = @{*$self}{ qw( AR Str Pos ) };
111    my @partial = ();
112
113    if ($Pos) {				### partial line...
114	@partial = (substr( $rArray->[ $Str++ ], $Pos ));
115	*$self->{Pos} = 0;
116    }
117    *$self->{Str} = scalar @$rArray;	### about to exhaust @$rArray
118    return (@partial,
119	    @$rArray[ $Str .. $#$rArray ]);	### remaining full lines...
120}
121
122#------------------------------
123#
124# print ARGS...
125#
126# Instance method, override.
127# Print ARGS to the underlying line array.
128#
129sub print {
130    if (defined $\ && $\ ne "\n") {
131	croak 'unsupported $\: must be "\n" or undef';
132    }
133
134    my $self = shift;
135    ### print STDERR "\n[[ARRAY WAS...\n", @{*$self->{AR}}, "<<EOF>>\n";
136    my @lines = split /^/, join('', @_); @lines or return 1;
137
138    ### Did the previous print not end with a newline?
139    ### If so, append first line:
140    if (@{*$self->{AR}} and (*$self->{AR}[-1] !~ /\n\Z/)) {
141	*$self->{AR}[-1] .= shift @lines;
142    }
143    push @{*$self->{AR}}, @lines;       ### add the remainder
144    ### print STDERR "\n[[ARRAY IS NOW...\n", @{*$self->{AR}}, "<<EOF>>\n";
145    1;
146}
147
148#------------------------------
1491;
150
151__END__
152
153
154=head1 VERSION
155
156$Id: Lines.pm 1248 2008-03-25 00:51:31Z warnes $
157
158
159=head1 AUTHORS
160
161
162=head2 Primary Maintainer
163
164David F. Skoll (F<dfs@roaringpenguin.com>).
165
166=head2 Principal author
167
168Eryq (F<eryq@zeegee.com>).
169President, ZeeGee Software Inc (F<http://www.zeegee.com>).
170
171
172=head2 Other contributors
173
174Thanks to the following individuals for their invaluable contributions
175(if I've forgotten or misspelled your name, please email me!):
176
177I<Morris M. Siegel,>
178for his $/ patch and the new C<getlines()>.
179
180I<Doug Wilson,>
181for the IO::Handle inheritance and automatic tie-ing.
182
183=cut
184
185