#
# Copyright 2003 Alexander Taler (dissent@0--0.org)
#
# All rights reserved. This program is free software; you can redistribute it
# and/or modify it under the same terms as Perl itself.
#

package VCS::LibCVS::Client::Connection;

use strict;
use Carp;

=head1 NAME

VCS::LibCVS::Client::Connection - a connection to a CVS server

=head1 SYNOPSIS

  my $conn = VCS::LibCVS::Client::Connection::SubClass->new();
  my $client = VCS::LibCVS::Client->new($conn, "/home/cvs");

=head1 DESCRIPTION

A connection to a CVS server.  Its only real use is to construct a CVS client.
It represents a generic connection, and so it cannot be instantiated, instead
you must choose a protocol to connect with the server, and instantiate the
appropriate subclass.

Once the connection is established, communication with the server takes place
through a pair of ::FileHandles.

=cut

###############################################################################
# Class constants
###############################################################################

use constant REVISION => '$Header: /cvs/libcvs/Perl/VCS/LibCVS/Client/Connection.pm,v 1.9 2003/06/27 20:52:33 dissent Exp $ ';

###############################################################################
# Private variables
###############################################################################

# Connection is a hash, and uses the following private entries.  The first
# group can be accesed by the subclasses, the second group should not be.
#
# Accessible to subclasses:
#
# FromServer => a ::FileHandle to read information from the server
# ToServer   => a ::FileHandle to write information to the server
#               These both must be set by subclasses upon connect().  They may
#               be destroyed by them on disconnect()
#
# Not Used by subclasses:
#
# Connected  => boolean, true if the Connection is connected
#               managed in connect() and disconnect()

###############################################################################
# Class routines
###############################################################################

# There is no constructor for this class.  You must choose one of its
# subclasses to use.

###############################################################################
# Instance routines
###############################################################################

=head1 INSTANCE ROUTINES

=head2 B<connect()>

$connection->connect()

=over 4

=item return type: undef

=back

Opens this connection to the server.  After calling this, the ::FileHandles for
accessing the server may be retrieved.

=cut

sub connect {
  my $self = shift;
  $self->{Connected} = 1;
  if ($VCS::LibCVS::Client::DebugLevel & VCS::LibCVS::Client::DEBUG_PROTOCOL) {
    $self->{ToServer}->prefix("C: ");
    $self->{FromServer}->prefix("S: ");
  }
}

=pod

=head2 B<disconnect()>

$connection->disconnect()

=over 4

=item return type: undef

=back

Closes this connection to the server.  ::FileHandles for communicating with the
server will no longer work.

=cut

sub disconnect {
  my $self = shift;
  $self->{Connected} = 0;
}

=pod

=head2 B<get_fh_to_server()>

$out_fh = $connection->get_fh_to_server();

=over 4

=item return type: ::FileHandle

=back

Returns an open writeable ::FileHandle.  Stuff written to it is sent to the
server.

The connection must be open to call this routine.

=cut

sub get_fh_to_server {
  my $self = shift;

  confess "Not connected" unless $self->connected();
  confess "Stream to server not found" unless defined ($self->{ToServer});
  return $self->{ToServer};
}

=pod

=head2 B<get_fh_from_server()>

$in_fh = $connection->get_fh_from_server();

=over 4

=item return type: ::FileHandle

=back

Returns an open readable ::FileHandle.  Responses generated by the server are read from this ::FileHandle.

The connection must be open to call this routine.

=cut

sub get_fh_from_server {
  my $self = shift;

  confess "Not connected" unless $self->connected();
  confess "Stream from server not found" unless defined ($self->{FromServer});
  return $self->{FromServer};
}

=pod

=head2 B<connected()>

$is_connected = $connection->connected();

=over 4

=item return type: boolean scalar

=back

Returns a scalar with a true value if the connection is open, false otherwise.

=cut

sub connected {
  my $self = shift;
  return $self->{Connected};
}

###############################################################################
# Private routines
###############################################################################

#
# DESTROY
#
# Clean up any connection
#

sub DESTROY {
  my $self = shift;
  $self->disconnect if $self->connected();
}

=pod

=head1 SEE ALSO

  VCS::LibCVS::Client
  VCS::LibCVS::Client::Connection::Local

=cut

1;
