package Plucene::Store::OutputStream;
=head1 NAME
Plucene::Store::OutputStream - a random-access output stream
=head1 SYNOPSIS
# isa Plucene::Store::InputStream
=head1 DESCRIPTION
This is an abstract class for output to a file in a Directory.
A random-access output stream.
Used for all Plucene index output operations.
=head1 METHODS
=cut
use strict;
use warnings;
no warnings 'uninitialized';
BEGIN { require Encode::compat if $] < 5.007001 }
use Encode qw(encode);
=head2 new
Create a new Plucene::Store::OutputStream
=cut
sub new {
my ($self, $filename) = @_;
$self = ref $self || $self;
open my $fh, '>', $filename
or die "$self cannot open $filename for writing: $!";
binmode $fh;
bless [ $fh, $filename ], $self;
}
=head2 clone
Clone this
=cut
sub clone {
my $orig = shift;
my $clone = $orig->new($orig->[1]);
CORE::seek($clone->[0], CORE::tell($orig->[0]), 0);
return $clone;
}
=head2 fh / read / seek / tell / getc / print / eof / close
File operations
=cut
use Carp 'croak';
sub fh { croak "OutputStream fh called" }
sub read { croak "OutputStream read called" }
sub seek { CORE::seek $_[0]->[0], $_[1], $_[2] }
sub tell { CORE::tell $_[0]->[0] }
sub getc { croak "OutputStream getc called" }
sub print { my $fh = shift->[0]; CORE::print $fh @_ }
sub eof { CORE::eof $_[0]->[0] }
sub close { CORE::close $_[0]->[0] }
=head2 write_byte
This will write a single byte.
=cut
sub write_byte {
CORE::print { $_[0]->[0] } $_[1];
}
=head2 write_int
This will write an int as four bytes.
=cut
sub write_int {
CORE::print { $_[0]->[0] } pack("N", $_[1]);
}
=head2 write_vint
This will write an int in a variable length format.
=cut
sub write_vint {
use bytes;
my $i = $_[1];
my $txt;
while ($i & ~0x7f) {
$txt .= chr($i | 0x80);
$i >>= 7;
}
$txt .= chr($i);
CORE::print { $_[0]->[0] } $txt;
}
=head2 write_long
This will write a long as eight bytes.
=cut
sub write_long {
CORE::print { $_[0]->[0] }
pack("NN", 0xffffffff & ($_[1] >> 32), 0xffffffff & $_[1]);
}
=head2 write_vlong
This will write a long in variable length format.
=cut
*write_vlong = *write_vint;
=head2 write_string
This will write a string.
=cut
sub write_string {
my $s = $_[1];
$s = encode("utf8", $s) if $s =~ /[^\x00-\x7f]/;
$_[0]->write_vint(length $s);
CORE::print { $_[0]->[0] } $s;
}
1;