position.cc #1

  • //
  • guest/
  • michael_shields/
  • src/
  • p4jrep/
  • position.cc
  • View
  • Commits
  • Open Download .zip Download (3 KB)
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>

#include <stdhdrs.h>
#include <strbuf.h>
#include <error.h>

#include "fileio.h"
#include "msgjrep.h"
#include "position.h"
#include "err.h"

#ifdef OS_FREEBSD
#define O_SYNC O_FSYNC
#endif

#define BUFSIZE 32

void Position::SetName( const char *journal, StrPtr *ival )
{
	name.Set( journal );
	name.Append( ".position" );

	if( ival )
	{
	    name.Append( "." );
	    name.Append( ival );
	}
}

void Position::SetOffset( off_tL soffset )
{
	offset = soffset;
}

char *Position::GetName()
{
	return name.Text();
}

off_tL Position::GetOffset()
{
	return offset;
}

bool Position::Init( const char *journal, StrPtr *ival, Error *e )
{
	SetName( journal, ival );

	return true;
}

bool Position::Open( Error *e )
{
	if( ( positionfd = open( GetName(),
	    O_RDWR | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR ) ) == -1 )
	    return syserr( "open", GetName(), e );

	return true;
}

bool Position::Seek( off_t poffset, const char *op, Error *e )
{
	if( lseek( positionfd, poffset, SEEK_SET ) == -1 )
	    return syserr( op, GetName(), e );

	return true;
}

bool Position::Read( Error *e )
{
	ssize_t n;
	char buf[ BUFSIZE ];

	ssize_t len;

	if( !Seek( 0, "read seek", e ) )
	    return false;

	if( ( n = read( positionfd, buf, BUFSIZE - 1 ) ) == -1 )
	    return syserr( "read", GetName(), e );

	if( n )
	{
	    /*
	     * Don't include the newline character (if present) in the
	     * string length of the offset read from the position file.
	     */
	    len = n - 1;
	    if( buf[ len ] != '\n' )
		len++;

	    buf[ len ] = '\0';

	    if( strspn( buf, "0123456789" ) != len )
	    {
		e->Set( MsgJrep::PosBadChars ) << GetName();
		return false;
	    }

	    if( !sscanf( buf, off_t_formatL, &offset ) )
	    {
		e->Set( MsgJrep::PosSscanfFail ) << GetName();
		return false;
	    }
	}
	else
	{
	    offset = 0;
	}

	return true;
}

bool Position::Increment( off_tL increment, Error *e )
{
	offset += increment;

	return true;
}

bool Position::Write( Error *e )
{
	char buf[ BUFSIZE ];
	int len;

	if( !Seek( 0, "write seek", e ) )
	    return false;

	sprintf( buf, off_t_formatL, offset );
	len = strlen( buf );
	buf[ len++ ] = '\n';

	if( write( positionfd, buf, len ) == -1 )
	    return syserr( "write", GetName(), e );

	return true;
}

bool Position::Truncate( Error *e )
{
	if( ftruncate( positionfd, 0 ) == -1 )
	    return syserr( "truncate", GetName(), e );

	return true;
}

bool Position::Close( Error *e )
{
	if( close( positionfd ) == -1 )
	    return syserr( "close", GetName(), e );

	return true;
}
# Change User Description Committed
#1 4839 Michael Shields Pushing p4jrep source into the public depot.