#pragma once
/*******************************************************************************
Copyright (c) 2010, Perforce Software, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE SOFTWARE, INC. BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/*******************************************************************************
* Name : P4BridgeClient.h
*
* Author : dbb
*
* Description : P4BridgeClient is a class derived from the ClientUser in the
* p4api. It provides the "UI" hooks for the p4api to return send output to the
* client app. It collects the output as a command is run so that the entire
* output can be retrieved when the command completes. Optionally, the client
* the client can register call back function to receive any or all of the
* output as it is generated by the p4api.
*
******************************************************************************/
// Forward ref.
class StrDict;
class StrBufDict;
class P4ClientMerge;
class P4ClientResolve;
class P4BridgeServer;
class P4Connection;
class DoublyLinkedList;
/*******************************************************************************
*
* These are the function prototypes for the call backs used to return data to
* the client as it is received from the p4api.
*
******************************************************************************/
typedef void __stdcall BinaryCallbackFn( int, void *, int );
typedef void __stdcall TextCallbackFn(int, const char*);
typedef void __stdcall IntIntIntTextCallbackFn(int, int, int, const char*);
typedef void __stdcall IntIntTextCallbackFn(int, int, const char*);
//typedef void __stdcall TextTextCallbackFn(const char*, const char*);
typedef void __stdcall IntTextTextCallbackFn(int, int, const char*, const char*);
typedef void _stdcall PromptCallbackFn( int, const char *, char *, int, int);
typedef int _stdcall ResolveCallbackFn( int, P4ClientMerge *);
typedef int _stdcall ResolveACallbackFn( int, P4ClientResolve *, int preview);
/*******************************************************************************
*
* KeyValuePair
*
* This simple class is used to return the data elements of a StrDict used to
* return tagged data.
*
******************************************************************************/
class KeyValuePair : p4base
{
public:
const int keyLength;
const char * key;
const int valLength;
const char * value;
KeyValuePair(const char * k, int klnth, const char * v, int vlnth);
virtual ~KeyValuePair();
virtual int Type(void) { return tKeyValuePair; }
};
/*******************************************************************************
*
* StrDictList
*
* Used to maintain a linked list of StrByDict objects for when more than one
* such object is returned by a command.
*
******************************************************************************/
class StrDictList : p4base
{
public:
StrDictList();
StrDictList* Next() { return pNext; }
void Next(StrDictList* pNew) { pNext = pNew; }
StrDict* Data() { return pStrDict; }
// virtual ~StrDictList() { if (pStrDict != NULL) delete pStrDict; if (pNext != NULL) delete pNext;};
virtual ~StrDictList();
virtual int Type(void) { return tStrDictList; }
private:
StrDict* pStrDict;
StrDictList* pNext;
};
/*******************************************************************************
*
* StrDictListIterator
*
* Provides the ability to iterate over a list of items (StrDicts )
* and their data produced by a command using tagged output
*
******************************************************************************/
class StrDictListIterator : p4base
{
public:
StrDictListIterator(StrDictList* ndict);
virtual ~StrDictListIterator();
int Init(StrDictList* ndict);
// Iterate over the items in the list
StrDictList* GetNextItem();
// Iterate the entries in the current item (StrDict)
KeyValuePair* GetEntry(int idx);
KeyValuePair* GetNextEntry();
// free any data held by the iterator and reset to star again
void Reset();
virtual int Type(void) { return tStrDictListIterator; }
private:
StrDictListIterator();
int idx;
StrDictList* curItem;
KeyValuePair* curEntry;
StrDictList* dict; // head of the list to iterate
};
/*******************************************************************************
*
* P4ClientError
*
* This simple class is used to return the data elements of an error message.
*
******************************************************************************/
class P4ClientError : p4base
{
public:
int Severity;
int ErrorCode;
char * Message;
P4ClientError * Next;
P4ClientError(int severity, int errorCode, const char * msg);
P4ClientError(P4ClientError * err);
virtual ~P4ClientError();
int MaxSeverity();
virtual int Type(void) { return tP4ClientError; }
};
/*******************************************************************************
*
* P4ClientInfoMsg
*
* This simple class is used to return the data elements of an info message.
*
******************************************************************************/
class P4ClientInfoMsg : p4base
{
public:
char Level;
int MsgCode;
char * Message;
P4ClientInfoMsg * Next;
P4ClientInfoMsg(int errorCode, char level, const char * msg);
P4ClientInfoMsg(P4ClientInfoMsg * err);
virtual ~P4ClientInfoMsg();
virtual int Type(void) { return tP4ClientInfoMsg; }
};
///*******************************************************************************
// *
// * P4FileSys
// *
// * This simple class is a FileSys object.
// *
// ******************************************************************************/
//
//class P4FileSys : p4base
//{
//public:
// P4FileSys(FileSys * merger);
// ~P4FileSys();
//
// static P4FileSys *CreateTemp( FileSysType type );
// static P4FileSys *CreateGlobalTemp( FileSysType type );
//
// int IsUnderPath( const char *path );
//
// virtual int Type(void) { return tP4P4P4FileSys; }
//
//private:
// ClientMerge * Message;
//
//};
/*******************************************************************************
*
* P4ClientMerge
*
* This simple class is a ClientMerge object.
*
******************************************************************************/
class P4ClientMerge : p4base
{
public:
P4ClientMerge(ClientMerge * merger);
~P4ClientMerge();
P4ClientError *GetLastError();
MergeStatus AutoResolve( MergeForce forceMerge );
MergeStatus Resolve();
MergeStatus DetectResolve();
int IsAcceptable();
StrPtr *GetBaseFile();
StrPtr *GetYourFile();
StrPtr *GetTheirFile();
StrPtr *GetResultFile();
int GetYourChunks();
int GetTheirChunks();
int GetBothChunks();
int GetConflictChunks();
const StrPtr *GetMergeDigest();
const StrPtr *GetYourDigest();
const StrPtr *GetTheirDigest();
virtual int Type(void) { return tP4ClientMerge; }
private:
ClientMerge * Merger;
Error err;
P4ClientError *lastError;
};
/*******************************************************************************
*
* P4ClientMerge
*
* This simple class is a wrapper for ClientMerge object.
*
******************************************************************************/
class P4ClientResolve : p4base
{
private:
ClientResolveA * Resolver;
static const Error _INVALID_API_REFERENCE;
Error err;
P4ClientError *lastError;
// P4ClientError *lastValue;
StrBuf type;
StrBuf mergeAction;
StrBuf yoursAction;
StrBuf theirAction;
StrBuf mergePrompt;
StrBuf yoursPrompt;
StrBuf theirPrompt;
StrBuf mergeOpt;
StrBuf yoursOpt;
StrBuf theirOpt;
StrBuf skipOpt;
StrBuf helpOpt;
StrBuf autoOpt;
StrBuf prompt;
StrBuf typePrompt;
StrBuf usageError;
StrBuf help;
public:
P4ClientResolve(ClientResolveA * resolver, int isUnicode);
~P4ClientResolve();
P4ClientError *GetLastError();
MergeStatus AutoResolve( MergeForce force ) const;
MergeStatus Resolve( int preview );
StrBuf &GetType() {return type;}
StrBuf &GetMergeAction() {return mergeAction;}
StrBuf &GetYoursAction() {return yoursAction;}
StrBuf &GetTheirAction() {return theirAction;}
// For the CLI interface, probably not of interest to others
StrBuf &GetMergePrompt() {return mergePrompt;}
StrBuf &GetYoursPrompt() {return yoursPrompt;}
StrBuf &GetTheirPrompt() {return theirPrompt;}
StrBuf &GetMergeOpt() {return mergeOpt;}
StrBuf &GetYoursOpt() {return yoursOpt;}
StrBuf &GetTheirOpt() {return theirOpt;}
StrBuf &GetSkipOpt() {return skipOpt;}
StrBuf &GetHelpOpt() {return helpOpt;}
StrBuf &GetAutoOpt() {return autoOpt;}
StrBuf &GetPrompt() {return prompt;}
StrBuf &GetTypePrompt() {return typePrompt;}
StrBuf &GetUsageError() {return usageError;}
StrBuf &GetHelp() {return help;}
virtual int Type(void) { return tP4ClientResolve; }
};
/*******************************************************************************
*
* P4BridgeClient
*
* Class derived from the ClientUser in the p4api. It provides the "UI" hooks
* for the p4api to return send output to the * client app. It collects
* the output as a command is run so that the entire * output can be
* retrieved when the command completes. Optionally, the client the client
* can register call back function to receive any or all of the output as
* it is generated by the p4api.
*
******************************************************************************/
class P4BridgeClient : public ClientUser, p4base
{
private:
// Callback function used to send tagged output to the client. Tagged or
// data is sent from the api as one or more StrDict objects representing
// one or more data objects. Each dictionary represents one data objects.
// I.e. for a list of file stats, each dictionary object will represent the
// data for one file. The data is stored as Key:Value pairs, i.e
// Filename:"MyCode.cpp"
//
// The function prototype is:
//
// void IntTextTextCallbackFn(int, const char*, const char*);
//
// The first parameter is an object ID, a given command can return
// multiple objects. ID's will start at 0 and increment for each
// successive object.
// The second parameter is the text 'key'
// The third parameter is the text value
//
// The client will receive the call back multiple times, once for each
// Key:Value pair in all of the dictionaries. For m data objects each
// with n Key:Value pairs, the client will receive m * n call backs. The
// object id can be used to group the data with there correct objects.
//
int objId;
// Simple linked list to hold the StrDict data returned as tagged output
// for a command.
StrDictList * results_dictionary_head;
StrDictList * results_dictionary_tail;
// Linked list to hold the errors (if any) returned by a command.
P4ClientError *pFirstError;
P4ClientError *pLastError;
// Store the concatenated error messages received in the execution of a
// command
//StrBuf *info_results;
// Linked list to hold the info output (if any) returned by a command.
P4ClientInfoMsg *pFirstInfo;
P4ClientInfoMsg *pLastInfo;
// Store the concatenated text output received in the execution of a
// command
StrBuf *text_results;
// Store the concatenated binary output received in the execution of a
// command as well as its size in bytes.
char * Binary_results;
int Binary_results_Count;
// Store the data for a command. Some commands, such as those which use
// spec data will use this override to obtain the data needed by the
// command. The data must be set before the command is run.
StrBuf *data_set;
// Save the error from an exception to be reported in the exception handler block
// to prevent possible recursion if it happens when reporting an error.
StrBuf * ExceptionError;
PromptCallbackFn * pPromptCallbackFn;
// Internal exception handler to handle platform exceptions i.e. Null
// pointer access
//int HandleException(unsigned int c, struct _EXCEPTION_POINTERS *e);
//P4BridgeClient();
P4Connection* pCon;
public:
// Construct + Destructor
P4BridgeClient(P4BridgeServer* pServer, P4Connection* pcon);
virtual ~P4BridgeClient(void);
virtual int Type(void) { return tP4BridgeClient; }
// Intercept and decode the messages received from the p4api.
// Based on there level, the will be processed as information or
// error messages.
virtual void Message( Error *err );
// These are the ClientUser overrides to receive the data back from the
// P4 server.
virtual void OutputBinary( const char *data, int length );
virtual void OutputText( const char *data, int length );
// virtual void OutputInfo( char level, const char *data );
virtual void OutputStat( StrDict *dict );
virtual void InputData( StrBuf *buf, Error *err );
virtual void HandleError( Error *err );
virtual void OutputError( const char *err ); // For broken servers
virtual void Diff( FileSys *f1, FileSys *f2, int doPage,
char *diffFlags, Error *e );
void HandleError( P4ClientError * pNewError );
void HandleError( int severity, int errorCode, const char *errMsg );
void HandleInfoMsg( int msgCode, char level, const char *infMsg );
void HandleInfoMsg( P4ClientInfoMsg * pNewMsg );
// Put the calls to the callback in Structured Exception Handlers to catch
// any problems in the call like bad function pointers.
void CallTextResultsCallbackFn( const char *data) ;
// void CallInfoResultsCallbackFn( char level, const char *data );
void CallInfoResultsCallbackFn( int msgID, char level, const char *data );
void CallTaggedOutputCallbackFn( int objId, const char *pKey, const char * pVal );
void CallErrorCallbackFn( int severity, int errorId, const char * errMsg );
void CallBinaryResultsCallbackFn(void * data, int length );
// Clear the results after a command completes and the results have been
// gathered by the client
void clear_results();
// StrDictListIterator to iterate through the resulting objects
// and Key:Value pairs
StrDictListIterator* GetTaggedOutput( );
// Get the error output after a command completes
P4ClientError * GetErrorResults();
void ClearErrorResults() {pFirstError = NULL; pLastError = NULL;}
// Set the data for a command. Some commands, such as those which use spec
// data will use this override to obtain the data needed by the command.
// The data must be set before the command is run.
void SetDataSet(const char * data);
StrPtr * GetDataSet( void );
void Prompt( const StrPtr &msg, StrBuf &rsp,
int noEcho, Error *e );
// Get the information output after a command completes
// Get the error output after a command completes
//StrBuf *GetInfoResults();
P4ClientInfoMsg * GetInfoResults();
// Get the text output after a command completes
StrBuf *GetTextResults();
// Get the binary output and its size after a command completes
int GetBinaryResultsCount() { return Binary_results_Count; }
void *GetBinaryResults();
// Callbacks for handling interactive resolve
int Resolve( ClientMerge *m, Error *e );
int Resolve( ClientResolveA *r, int preview, Error *e );
private:
P4BridgeServer* pServer;
int Resolve_int( P4ClientMerge *merger);
int Resolve_int( P4ClientResolve *resolver, int preview, Error *e);
//P4BridgeServer* Server() {return (P4BridgeServer*) pServer;}
//
//private:
// P4BridgeClient() {};
};