The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
=pod

=head1 NAME

Data::Range::Compare::Stream::Iterator::Base - Abstract class

=head1 SYNOPSIS

  package MyIterator;
  use strict;
  use warnings;
  use IO::File;
  use IO::Select;
  use base qw(Data::Range::Compare::Stream::Iterator::Base);
  use Data::Range::Compare::Stream;
  
  sub new {
    my ($class,%args)=@_;
    my $has_next;
    my $self=$class->SUPER::new(%args);
  
    if(defined($args{filename})) {
      my $fh=IO::File->new($args{filename});
      if($fh) {
         $self->{fh}=$fh;
         my $line=$fh->getline;
         $self->{next_line}=$line;
         $has_next=defined($line);
      } else {
        $self->{msg}="Error could not open $args{filename} error was: $!";
      }
  
    }
  
    $self->{has_next}=$has_next;
    return $self;
  }
  
  sub get_next {
    my ($self)=@_;
    return undef unless $self->has_next;
  
    my $line=$self->{next_line};
    $self->{next_line}=$self->{fh}->getline;
    $self->{has_next}=$self->{next_line} ?  1 : 0;
  
    chomp $line;
    return new Data::Range::Compare::Stream(split /\s+/,$line);
  }
  
  1;

=head1 DESCRIPTION

This module acts as the base class for all Data::Range::Compare::Stream::Iterator classes.

=head2 Methods to implement

=over 3

=item * my $iterator=new MyIterator(arguments=>here);

The default object constructor takes a hash of arguments, and returns a blessed anonymous hash.  If you want to do anything other than that you will need to overload this function!

=item * while($iterator->has_next) { do something }

The internals return $self->{has_next}. If you want to do anything other than that you will need to overload this function!

=item * my $range=$iterator->get_next;

Objects returned from this function should extend Data::Range::Compare::Stream::Result::Base

=item * my $string=$iterator->to_string;

Returns the package name of $iterator

=item * $iterator->on_consolidate;

This object needs to be called when ranges are being consolidated.

=item * $iterator->delete_from_root($id);

Deletes $id from $iterator.

=item * if($iterator->is_child) { ... }

Returns true if the object was auto generated by another object.

=item * if($iterator->has_child) { ... }

Returns true if this $iterator auto generated a new iterator object

=item * my $id=$iterator->get_column_id

Returns the column id of this $iterator.

=item * $iterator->set_column_id($id);

Sets the column id of $iterator

=item * if($iterator->has_root) { ... }

Returns true if this $iterator was auto generated by another iterator.

=item * my $root=$iterator->get_root;

Returns the root object if $iterator->has_root is true.

=item * my $id=$iterator->get_root_column_id;

Returns the column_id of the object that auto generated $iterator, returns current column_id of the object was not auto generated.

=item * my $child=$iterator->get_child;

Returns the child object if $iterator->has_child is true.

=item * my $id=$iterator->get_child_column_id;

Returns the child column_id if $iterator->has_child is true.

=item * my $line=$iterator->result_to_line($range);

Given a $result from $iterator->get_next, this interface converts the $range object into a line that can be parsed by $iterator->parse_line($line).  Think of this function as a data serializer for range objects generated by an $iterator object.  When overloading this function or using a call back make sure result_to_line can be parsed by parse_line.

  sub result_to_line {
    my ($self,$result)=@_;
    return $self->{result_to_line}->($result) if defined($self->{result_to_line});

    my $range=$result->get_common;
    my $line=$range->range_start_to_string.' '.$range->range_end_to_string."\n";
    return $line;
  }

=item *  my $ref=$iterator->parse_line($line);

Given a $line returns the arguments required to construct an object that extends or implements Data::Range::Compare::Stream.  When overloading or passing in constructor arguments that provide a call back make sure result_to_line produces the expected line parse_line expects.

  sub parse_line {
    my ($self,$line)=@_;
    return $self->{parse_line}->($line) if defined($self->{parse_line});
    chomp $line;
    [split /\s+/,$line];
  }


=back

=head1 SEE ALSO

Data::Range::Compare::Stream::Cookbook

=head1 AUTHOR

Michael Shipper

=head1 Source-Forge Project

As of version 0.001 the Project has been moved to Source-Forge.net

L<Data Range Compare|https://sourceforge.net/projects/data-range-comp/>
L<https://sourceforge.net/projects/data-range-comp/>

=head1 COPYRIGHT

Copyright 2011 Michael Shipper.  All rights reserved.

This library is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.

=cut