Performing file I/O

The default client file I/O implementation returns a FileSys object, which is described in filesys.h. To intercept client workspace file I/O, replace the FileSys *ClientUser::File() method by subclassing ClientUser.

The following example illustrates how you can override FileSys.

#include "p4/clientapi.h"
class MyFileSys : public FileSys {
    public:

    MyFileSys();
    ~MyFileSys();

    virtual void    Open( FileOpenMode mode, Error *e );
    virtual void    Write( const char *buf, int len, Error *e );
    virtual int     Read( char *buf, int len, Error *e );
    virtual int     ReadLine( StrBuf *buf, Error *e );
    virtual void    Close( Error *e );
    virtual int     Stat();
    virtual int     StatModTime();
    virtual void    Truncate( Error *e );
    virtual void    Unlink( Error *e = 0 );
    virtual void    Rename( FileSys *target, Error *e );
    virtual void    Chmod( FilePerm perms, Error *e );

    protected:
    int nchars;
} ;

MyFileSys::MyFileSys()
{
    nchars = 0;
}

MyFileSys::~MyFileSys()
{
    printf( "Number of characters transferred = %d\n", nchars );
}

void MyFileSys::Open( FileOpenMode mode, Error *e )
{
    printf( "In MyFileSys::Open()\n" );
}

void MyFileSys::Write( const char *buf, int len, Error *e )
{
    printf( "In MyFileSys::Write()\n" );
    printf( "%s", buf );
    nchars = nchars + len;
}

int MyFileSys::Read( char *buf, int len, Error *e )
{
    printf( "In MyFileSys::Read()\n" );
    return 0;
}

int MyFileSys::ReadLine( StrBuf *buf, Error *e )
{
    printf( "In MyFileSys::ReadLine()\n" );
    return 0;
}
void MyFileSys::Close( Error *e )
{
    printf( "In MyFileSys::Close()\n" );
}

int MyFileSys::Stat()
{
    printf( "In MyFileSys::Stat()\n" );
    return 0;
}

int MyFileSys::StatModTime()
{
    printf( "In MyFileSys::StatModTime()\n" );
    return 0;
}

void MyFileSys::Truncate( Error *e )
{
    printf( "In MyFileSys::Truncate()\n" );
}

void MyFileSys::Unlink( Error *e = 0 )
{
    printf( "In MyFileSys::Unlink()\n" );
}

void MyFileSys::Rename( FileSys *target, Error *e )
{
    printf( "In MyFileSys::Rename()\n" );
}

void MyFileSys::Chmod( FilePerm perms, Error *e )
{
    printf( "In MyFileSys::Chmod()\n" );
}

class ClientUserSubclass : public ClientUser {
    public:
    virtual FileSys *File( FileSysType type );
};

FileSys *ClientUserSubclass::File( FileSysType type )
{
    return new MyFileSys;
}
int main( int argc, char **argv )
{
    ClientUserSubclass ui;
    ClientApi client;
    Error e;

    char force[] = "-f";
    char file[] = "hello.c";
    char *args[2] = { &force[0], &file[0] };

    // Connect to server

    client.Init( &e );
    e.Abort();

    // Run the command "sync -f hello.c"

    client.SetArgv( 2, &args[0] );
    client.Run( "sync", &ui );

    // Close connection

    client.Final( &e );
    e.Abort();
    return 0;
}

The preceding program produces the following output when you run it.

% ls -l hello.c
-r--r--r--    1 member   team           41 Jul 30 16:57 hello.c
% cat hello.c
main()
{
  printf( "Hello World!\n" );
}
% samplefilesys
//depot/main/hello.c#1 - refreshing /work/main/hello.c
In MyFileSys::Stat()
In MyFileSys::Open()
In MyFileSys::Write()
main()
{
   printf( "Hello World!\n" );
}
In MyFileSys::Close()
Number of characters transferred = 41