|
CStageManager class |
Pipelines v2.0 |
|
Description |
The CStageManager() class provides access to a range of
stage resources, including; parsing, extracting and validating your stage
command argument, issuing error and warning messages on behalf of your stage,
reading and writing input and output stream records, testing stream
connectivity and other general purpose support functions. The StageManager is
at the core of Pipelines and it serves as a central class which provides an
interface to essential stage services that allow you to control how your stage
operates in a multi-stream pipeline configuration.
|
Definition |
The following class definition is
an edited version; it details only those members which are accessible and of
use to you. In addition; any examples that may be shown are only intended as a
demonstration of how certain functions might be used, they do not represent
best practice nor do they take into account the scope and de-allocation of
class objects.
// Definitions for interface to stage DLLs.typedef DWORD ( *BEGIN_STAGE )( CStageInitInfo *a_pManager );#define BEGIN_STAGE_FCN "BeginStage" class CStageManager { public: // Pipeline, Stage and Stream functions. CStage *GetStage( CProcess &a_Process ); bool ReadRecord( CProcess &a_Process, DWORD a_dwInStream, CString *a_pBuffer ); bool ReadAnyRecord( CProcess &a_Process, CString *a_pBuffer ); bool PeekRecord( CProcess &a_Process, DWORD a_dwInStream, CString *a_pBuffer ); int PeekAnyRecord( CProcess &a_Process, CString *a_pBuffer ); bool WriteRecord( CProcess &a_Process, DWORD a_dwOutStream, CString *a_pszRecord ); bool ConsumeRecord( CProcess &a_Process, DWORD a_dwInStream ); void StageMessage( CProcess &a_Process, DWORD a_dwType, const char *a_pMessage, ... ); bool StageMessage( CProcess &a_Process, DWORD a_dwMsgNumber, DWORD a_dwType, ... );bool RuntimeError( void ) const;
double GetProcId( void ) const; bool PreProcess( CProcess &a_pProcess, const char **a_pszArgument ); void SeverOutStream( CProcess &a_Process, DWORD a_dwStream ); void SeverInStream( CProcess &a_Process, DWORD a_dwStream ); // Parsing functions. bool ParseForToken( CToken *a_pToken ); bool ParseForIntegerString( CIntegerString *a_pIntString );bool ParseForDoubleString( CDoubleString *a_pDblString );
bool ParseForCharacterString( CCharacterString *a_pCharString ); bool ParseForRegExp( CProcess &a_Process, CRegExpression *a_pRegExp, bool a_bCaseSensitive = true ); bool ParseForIntegerRange( CIntegerRange *a_pIntRange ); bool ParseForCharacter( CCharacterString *a_pCharString ); bool ParseForCharacterRange( CCharacterRange *a_pCharRange ); // Conversion functions.
bool ConvertToInteger( CIntegerString *a_pIntString );
bool ConvertToDouble( CDoubleString *a_pDblString );
// Runtime extraction functions. void ExtractColumnRange( CExtractRange *a_pRange ); void ExtractWordRange( CExtractRange *a_pRange ); void ExtractFieldRange( CExtractRange *a_pRange ); bool RegExpMatch( CRegExpression *a_pRegExp, CString &a_szSource ); bool PatternMatch( const char *a_pszPattern, const char *a_pszSource ); // Set the status of a stage once initialisation is complete.
bool SetStatus( CStageInitInfo *a_pInfo );
// ooRexx
interface functions.
RexxExitContext *GetRexxExitContext(
void );
RexxDirectoryObject GetRexxDirectoryObject(
void );
DWORD GetRexxVariable(
const char *a_pszName, CString *a_pszValue );
bool GetRexxStem( const char *a_pszName,
std::list< CString > *a_plStem );
bool GetRexxArray(const char *a_pszName,
std::list< CString > *a_plArray );
DWORD GetRexxStemEntry(
const char *a_pszName, CString *a_pszValue, DWORD a_dwIndex );
DWORD GetRexxArrayEntry(
const char *a_pszName, CString *a_pszValue, DWORD a_dwIndex );
DWORD GetRexxStemSize(
const char *a_pszName );
DWORD GetRexxArraySize(
const char *a_pszName );
bool IsRexxVariable(const
char *a_pszName, DWORD a_dwType );
bool IsRexxStem( const
char *a_pszName );
bool IsRexxArray( const
char *a_pszName );
CRexxEntry *AddRexxEntry( void );
};|
Member variables |
None.|
Member functions |
CStage *CStageManager::GetStage( _in CProcess &a_Process ); |
|
● |
Purpose Use GetStage() to get a pointer to your CStage. With this pointer; you can access your stage arguments,
determine your position in the pipeline, set and test your input and output
stream connections and more. |
||
|
● |
Parameters |
||
|
|
|
||
|
● |
Returns |
||
|
|
|
||
|
● |
Messages None |
||
|
● |
Usage To get a pointer to your CStage object: DWORD CMyStage::Go( void ){ // Access the manager.CStageManager *pManager = Manager(); // Access my stage. CStage *pStage = pManager->GetStage( *this ); ... return( _RC_SUCCESS_ );} |
bool CStageManager::ReadRecord( _in CProcess &a_Process, _in DWORD a_dwInStream, _inout CString *a_pszRecord ); |
|
● |
Purpose Use ReadRecord() to read a record from the specified
input stream a_dwInStream. ReadRecord() issues a read request against the specified
input stream a_dwInStream. The function
waits for a record to become available; effectively suspending your stage
until the read can be satisfied. The length of time that your stage remains
suspended cannot be determined. Once a record has become available; the
function stores that record in the CString buffer a_pszRecord,
removes the record from the input stream (releasing the stage connected to
the write-end of the stream, from its suspended state) and returns control to
your stage. A stage which calls ReadRecord(); delays the records. |
||||||
|
● |
Parameters |
||||||
|
|
|
||||||
|
● |
Returns |
||||||
|
|
|
||||||
|
● |
Messages None |
||||||
|
● |
Usage To read a record from your primary input stream: DWORD CMyStage::Go( void ){ // Access the manager.CStageManager *pManager = Manager(); // Record buffer. CString szRecord; while( true ) { // Read a record from my primary input stream. if( !pManager->ReadRecord( *this, 0, &szRecord ) ) { // This is the end-of-file on my primary input stream. break; } // // TODO: operate on the record here. // ... // Write the record to my primary output stream. if( !pManager->WriteRecord( *this, 0, &szRecord ) ) { // This is the end-of-file on my primary output stream. break; } } return( _RC_SUCCESS_ );} |
bool CStageManager::ReadAnyRecord( _in CProcess &a_Process, _inout CString *a_pszRecord ); |
|
● |
Purpose Use ReadAnyRecord() to read a record from any connected
input stream. ReadAnyRecord() issues a read request against all your
input streams. The function waits for a record to become available on any input
stream; effectively suspending your stage until the read can be satisfied.
The length of time that your stage remains suspended cannot be determined.
Once a record has become available; the function stores that record in the
CString buffer a_pszRecord,
removes the record from the input stream (releasing the stage connected to
the write-end of the stream, from its suspended state) and returns control to
your stage. A stage which calls ReadAnyRecord(); delays the records. |
||||
|
● |
Parameters |
||||
|
|
|
||||
|
● |
Returns |
||||
|
|
|
||||
|
● |
Messages None |
||||
|
● |
Usage To read a record from any of your input streams: DWORD CMyStage::Go( void ){ // Access the manager.CStageManager *pManager = Manager(); // Record buffer. CString szRecord; while( true ) { // Read a record from any of my input streams. int nStream = pManager->ReadAnyRecord( *this, &szRecord ); // Test for end-of-file. if( nStream < 0 ) { // This is the end-of-file on all my input streams. break; } // // TODO: operate on the record here. // ... // Write the record to my primary output stream. if( !pManager->WriteRecord( *this, 0, &szRecord ) ) { // This is the end-of-file on my primary output stream. break; } } return( _RC_SUCCESS_ );} |
bool CStageManager::PeekRecord( _in CProcess &a_Process, _in DWORD a_dwInStream, _inout CString *a_pszRecord ); |
|
● |
Purpose Use PeekRecord() to peek at a record on the specified
input stream a_dwInStream. PeekRecord() issues a read request against the specified
input stream a_dwInStream. The function
waits for a record to become available; effectively suspending your stage
until the read can be satisfied. The length of time that your stage remains
suspended cannot be determined. Once a record has become available; the
function stores that record in the CString buffer a_pszRecord,
but does not remove the record from the input stream (leaving the stage
connected to the write-end of the stream, in its suspended state) and returns
control to your stage. A stage which calls PeekRecord(), then WriteRecord(),
then ConsumeRecord(),
in that order; does not delay the records. |
||||||
|
● |
Parameters |
||||||
|
|
|
||||||
|
● |
Returns |
||||||
|
|
|
||||||
|
● |
Messages None |
||||||
|
● |
Usage To peek at a record on your primary input stream: CMyStage::Go( void ){ // Access the manager.CStageManager *pManager = Manager(); // Record buffer. CString szRecord; while( true ) { // Peek at a record on my primary input stream. if( !pManager->PeekRecord( *this, 0, &szRecord ) ) { // This is the end-of-file on my primary input stream. break; } // // TODO: operate on the record here. // ... // Write the record to my primary output stream. if( !pManager->WriteRecord( *this, 0, &szRecord ) ) { // This is the end-of-file on my primary output stream. break; } // Release the stage that I read from. pManager->ConsumeRecord( *this, 0 ); } return( _RC_SUCCESS_ );} |
int CStageManager::PeekAnyRecord( _in CProcess &a_Process, _inout CString *a_pszRecord ); |
|
● |
Purpose Use PeekAnyRecord() to peek at a record on any connected
input stream. PeekAnyRecord() issues a read request against all your
input streams. The function waits for a record to become available on any input
stream; effectively suspending your stage until the read can be satisfied.
The length of time that your stage remains suspended cannot be determined.
Once a record has become available; the function stores that record in the
CString buffer a_pszRecord,
but does not remove the record from the input stream (leaving the stage
connected to the write-end of the stream, in its suspended state) and returns
control to your stage. A stage which calls PeekAnyRecord(), then WriteRecord(),
then ConsumeRecord(),
in that order; does not delay the records. |
||||
|
● |
Parameters |
||||
|
|
|
||||
|
● |
Returns |
||||
|
|
|
||||
|
● |
Messages None |
||||
|
● |
Usage To peek at a record from any of your input streams: CMyStage::Go( void ){ // Access the manager.CStageManager *pManager = Manager(); // Record buffer. CString szRecord; while( true ) { // Peek at a record on any of my input streams. int nStream = pManager->PeekAnyRecord( *this, &szRecord ); // Test for end-of-file. if( nStream < 0 ) { // This is the end-of-file on all my input streams. break; } // // TODO: operate on the record here. // ... // Write the record to my primary output stream. if( !pManager->WriteRecord( *this, 0, &szRecord ) ) { // This is the end-of-file on my primary output stream. break; } // Release the stage that I read from. pManager->ConsumeRecord( *this, nStream ); } return( _RC_SUCCESS_ );} |
bool CStageManager::WriteRecord( _in CProcess &a_Process, _in DWORD a_dwOutStream, _in CString *a_pszRecord ); |
|
● |
Purpose Use WriteRecord() to write a record to the specified
output stream a_dwOutStream. WriteRecord() writes the record from the CString buffer a_pszRecord
to the specified output stream a_dwOutStream.
The function suspends your stage until the target stage connected to output
stream a_dwOutStream has consumed
the record. That is to say; your stage remains suspended pending service by
the StageManager until it is released by a call on the read-end of the
stream, through any of the functions; ReadRecord(), ReadAnyRecord()
or ConsumeRecord().
The length of time that your stage remains suspended cannot be determined.
Once the record has been consumed; the function releases your stage from its
suspended state and returns control to your stage. |
||||||
|
● |
Parameters |
||||||
|
|
|
||||||
|
● |
Returns |
||||||
|
|
|
||||||
|
● |
Messages None |
||||||
|
● |
Usage To write a record to your primary output stream: CMyStage::Go( void ){ // Access the manager.CStageManager *pManager = Manager(); // Record buffer. CString szRecord; while( true ) { // Read a record from my primary input stream. if( !pManager->ReadRecord( *this, 0, &szRecord ) ) { // This is the end-of-file on my primary input stream. break; } // // TODO: operate on the record here. // ... // Write the record to my primary output stream. if( !pManager->WriteRecord( *this, 0, &szRecord ) ) { // This is the end-of-file on my primary output stream. break; } } return( _RC_SUCCESS_ );} |
bool CStageManager::ConsumeRecord( _in CProcess &a_Process, _in DWORD a_dwInStream ); |
|
● |
Purpose Use ConsumeRecord() to remove a record from the specified
input stream a_dwInStream. ConsumeRecord() removes a record from the specified input
stream a_dwInStream (releasing the
stage connected to the write-end of the stream, from its suspended state) and
returns control to your stage. There must be a record in the input stream for
ConsumeRecord()
to remove; you must first have made a call to either the PeekRecord()
or PeekAnyRecord()
function before making a call to ConsumeRecord(). Both peek functions
issue a read record request but they do not automatically consume the record
once the read is complete (leaving the stage connected to the write-end of
the stream, in its suspended state). ConsumeRecord() allows you to remove
an input stream record as and when you require. A stage which calls PeekRecord() or PeekAnyRecord(), then
WriteRecord(),
then ConsumeRecord(), in that order; does not delay the records. |
||||
|
● |
Parameters |
||||
|
|
|
||||
|
● |
Returns |
||||
|
|
|
||||
|
● |
Messages None |
||||
|
● |
Usage To create a stage which does not delay the records; use
the following construct: CMyStage::Go( void ){ // Access the manager.CStageManager *pManager = Manager(); // Record buffer. CString szRecord; while( true ) { // Peek at a record on my primary input stream. if( !pManager->PeekRecord( *this, 0, &szRecord ) ) { // This is the end-of-file on my primary input stream. break; } // // TODO: operate on the record here. // ... // Write the record to my primary output stream. if( !pManager->WriteRecord( *this, 0, &szRecord ) ) { // This is the end-of-file on my primary output stream. break; } // Release the stage that I read from. pManager->ConsumeRecord( *this, 0 ); } return( _RC_SUCCESS_ );} |
void CStageManager::StageMessage( _in CProcess &a_Process, _in DWORD a_dwType, _in_opt const char *a_pMessage, _in_opt ... ); |
|
● |
Purpose Use StageMessage() to write a synchronised stage message
to the console. In a multi-stage, multi-pipeline configuration; at any
one time there may be more than one stage writing messages to the console at
the same time, and their output must be managed in order to prevent output
overlap. CApplMessage()
provides this mechanism, by locking the console for output; it ensures that
messages from multiple output sources are written uninterrupted and in the
correct sequence. You should use this version of StageMessage() when you want
to write a free-form message to the console. There are two flavours of StageMessage(); this version,
and the canned message version; which follows, and
both allow you to write a warning or error message to the console. |
||||||||
|
● |
Parameters |
||||||||
|
|
|
||||||||
|
● |
Returns
|
||||||||
|
● |
Messages None |
||||||||
|
● |
Usage To issue a free-form message; simply specify the message
as an operand on the StageMessage function: bool CMyStage::Initialise( void ){ // Access the manager.CStageManager *pManager = Manager(); // Access my stage. CStage *pStage = pManager->GetStage( *this ); pStage->MinInStreamsRequired( 1 ); pStage->MaxInStreamsAllowed( 2 ); pStage->MinOutStreamsRequired( 1 ); pStage->MaxOutStreamsAllowed( 1 ); // Point to my command argument. const char *pszArgument = pStage->Argument(); // My stage allows up to two input streams to be connected, however, if there // is only one input stream connected; then warn the user. CInStream *pInStream = pStage->GetInStream( 1 ); if( pInStream && pInStream->IsDisConnected() ) { // My secondary input stream is not connected! pManager->StageMessage( *this, _WARNING_, “There is only one input stream connected!” ); ... } ... return( true );} |
bool CStageManager::StageMessage( _in CProcess &a_Process, _in DWORD a_dwMsgNumber, _in DWORD a_dwType, _in_opt ... ); |
|
● |
Purpose Use StageMessage() to write a synchronised stage message
to the console. In a multi-stage, multi-pipeline configuration; at any
one time there may be more than one stage writing messages to the console at
the same time, and their output must be managed in order to prevent output
overlap. CApplMessage()
provides this mechanism, by locking the console for output; it ensures that
messages from multiple output sources are written uninterrupted and in the
correct sequence. You should use this version of StageMessage() when you want
to write a canned message to the console. There are two flavours of StageMessage(); this version,
and the free-form message version; which precedes, and both allow you to write
a warning or error message to the console. |
||||||||
|
● |
Parameters |
||||||||
|
|
|
||||||||
|
● |
Returns |
||||||||
|
|
|
||||||||
|
● |
Messages None |
||||||||
|
● |
Usage To issue a specific canned stage message; simply specify
the canned message number as an operand on the StageMessage function: bool CMyStage::Initialise( void ) { // Access the manager.CStageManager *pManager = Manager(); // Access my stage. CStage *pStage = pManager->GetStage( *this ); pStage->MinInStreamsRequired( 1 ); pStage->MaxInStreamsAllowed( 2 ); pStage->MinOutStreamsRequired( 1 ); pStage->MaxOutStreamsAllowed( 1 ); // Point to my command argument. const char *pszArgument = pStage->Argument(); // My stage does not require a command argument; if there is one, // then it is unexpected. if( *pszArgument ) { // Tell the user the type of argument that I expect; issue canned // stage message number 33. pManager->StageMessage( *this, 33, _ERROR_, pszArgument ); return( false ); } return( true );} |
bool CStageManager::RuntimeError( void ) const; |
|
● |
Purpose Use RuntimeError() to determine if the StageManager has
issued a runtime quiesce command. When any of the stage’s in a pipeline report a runtime
error (by returning a value of _RC_FAIL_ from their required stage DLL
interface function Go() ) the StageManager begins terminating the pipeline by
first setting the runtime quiesce flag, which indicates that the pipeline is
quiescent. Next the StageManager disconnects the input and output stream
connections for your stage; which will cause the next input read or output
write request to fail, allowing your stage to terminate, as if at
end-of-file. However, Pipelines is not pre-emptive; the StageManager must
first wait for all active stages in the pipeline to request one of its stream
services in order to detect that the pipeline is terminating. Your stage may
not request i/o on a regular basis; it may for example, sort its input
records, which may consist of millions or more entries; where your stage may
be pre-occupied for a considerable amount of time and will not be reading or
writing any input or output records. The RuntimeError() function allows you
to check if the quiesce command has been issued by the StageManager, as an
when you need to; so that your stage does not cause the pipeline to
‘seemingly’ hang while your stage needlessly continues with its runtime
phase; in a pipeline that is waiting to terminate. |
||
|
● |
Parameters |
||
|
|
|
||
|
● |
Returns |
||
|
|
|
||
|
● |
Messages None |
||
|
● |
Usage The following example shows an edited excerpt from the CSort
stage commands’ multiple-key-field recursive sort mechanism. The
RuntimeError() function ensures that the RecurseCompare() function un-winds
once a runtime error has occurred: bool CSort::RecurseCompare( const CString *l, const CString *r, std::vector< m_Position >::iterator iPos ){ // Check if the pipeline is quiescing. if( m_pManager->RuntimeError() ) return( false ); // iPos points to the current sort range. // So, extract/isolate the portion defined by iPos and validate the comparison. m_Position *pPos = &( *iPos ); DWORD dwFrom = pPos->m_dwFrom - 1; DWORD dwFor = pPos->m_dwTo - dwFrom; CString szlMid = l->Mid( dwFrom, dwFor ); CString szrMid = r->Mid( dwFrom, dwFor ); ... // The comparison moves down to the next level. if( szlMid == szrMid ) { if( ( iPos + 1 ) != m_vPosition.end() ) return( RecurseCompare( l, r, iPos + 1 ) ); } if( pPos->m_bAscending ) return( szlMid < szrMid ); return( szlMid > szrMid ); } |
double CStageManager::GetProcId( void ) const; |
|
● |
Purpose Use GetProcId() to get the Process Identification number
of the StageManager. Many of the builtin stages’ that are provided with
Pipelines use this number when creating uniquely identifiable names for a
range of objects, including; events, mutexes and work files. By using the
Process Identification number of the StageManager as part of a name for a
global resource, it may help when debugging your new stage. As multiple
instances of Pipelines may execute concurrently (and that might mean multiple
instances of identical pipelines, with multiple instances of your new stage);
creating events, mutexes and work filenames with this number in combination
with your pipeline and stage number can make identifying which resource
belongs to which pipeline and stage, a great deal easier. |
||
|
● |
Parameters
|
||
|
● |
Returns |
||
|
|
|
||
|
● |
Messages None |
||
|
● |
Usage To create a work filename which uniquely identifies your
stage as the owner; you might use the following approach: bool CMyStage::Initialise( void ) { // Access the manager.CStageManager *pManager = Manager(); // Access my stage. CStage *pStage = pManager->GetStage( *this ); ... // Create a unique filename. CString szTmpFile;szTmpFile.Format( "TEMP-%.5d%.3d%.3d.txt", ( DWORD )pManager->GetProcId(), Pipeline(), Stage() ); ... return( true );} |
bool CStageManager::PreProcess( _in CProcess &a_Process, _inout const char **a_pszArgument ); |
|
● |
Purpose Use PreProcess() to extract the stage command arguments
specified in the CASEI()
and ZONE()
pre-process functions. There are a number of builtin
Pipelines stage’s which operate as simple selection filters; writing records
to their primary and secondary output streams, depending on the content of an
input record. Consider the FROMLABEL stage for example. By default, all of
these filter type stage’s check for the existence/or not of the specified
text starting in the first column of an input record. However, the PreProcess()
function extends this basic selection capability; instructing the
manager to extract a substring of the record, determined by the column, word
or field range, and optionally; to translate both the stage operands and the content of the input records to uppercase,
and present this altered record to the stage
when a read-record is requested. The function does not alter the way in
which a stage processes its input and output records, it only
alters the format of the record which is presented to the stage. When the stage performs a subsequent
write-record request, the manager writes the original unmodified input record
to the specified output stream. PreProcess() ensures that the stage command argument
syntax for a position or range on which to operate is identical for all
filter type stages. |
||||
|
● |
Parameters |
||||
|
|
|
||||
|
● |
Returns |
||||
|
|
|
||||
|
● |
Messages None |
||||
|
● |
Usage To enable CASEI() or ZONE()
pre-processing: bool CMyStage::Initialise( void ) { // Access the manager.CStageManager *pManager = Manager(); // Access my stage. CStage *pStage = pManager->GetStage( *this ); ... // Point to my command argument. const char *pszArgument = pStage->Argument(); // Perform any preprocessing required.if( !pManager->PreProcess( *this, &pszArgument ) ) return( false ); // My stage requires a delimted string. CString szString; CCharacterString *pCharString = new CCharacterString( *this );pCharString->m_bRequired = true; pCharString->m_pszSource = &pszArgument; pCharString->m_pszTarget = &szString; // Extract the string. if( !pManager->ParseForCharacterString( pCharString ) ) return( false ); ... return( true );} Excerpt The following example shows how
the ZONE()
pre-process function greatly extends the selection capability of mystage. By using the PreProcess()
function; mystage is able to
restrict the selection of records to those that contain the phrase text to find in the third-from-last
(+) delimited word of each input record. pipe < myfile.txt ... | mystage zone( ws ‘+’ w-3 ) /text to find/ | > textfound.txt |
void CStageManager::SeverOutStream( _in CProcess &a_Process, _in DWORD a_dwOutStream ); |
|
● |
Purpose Use SeverOutStream() to disconnect the specified output stream a_dwOutStream. SeverOutStream() disconnects both
the specified output stream a_dwOutStream
and the corresponding input stream of the stage connected to the read-end of
the stream. If it is suspended; the stage connected to the read-end of the
stream is released from its suspended state and the stage regains control
immediately. Any subsequent read request made on the read-end of the stream
will return an end-of-file condition. |
||||
|
● |
Parameters |
||||
|
|
|
||||
|
● |
Returns
|
||||
|
● |
Messages None |
||||
|
● |
Usage To disconnect
an output stream: DWORD CMyStage::Go( void ) { // Access the manager.CStageManager *pManager = Manager(); // Access my stage. CStage *pStage = pManager->GetStage( *this ); ... // My stage writes only the first 100 input stream records to its // primary output stream. The stage then disconnects its primary // output stream and begins writing input stream records to its // secondary output stream. // The target output stream is initially the primary output stream. DWORD dwOutStream = 0; // Record buffer. CString szRecord; // Accumulate the number of input records read. DWORD dwRecCount = 0; while( true ) { // Read a record from my primary input stream.if( !pManager->ReadRecord( *this, 0, &szRecord ) ) { // This is the end-of-file on my primary input stream. break; } if( dwRecCount == 100 ) { pManager->SeverOutStream( 0 ); // Switch to my secondary output stream. dwOutStream = 1; } // Write the record to the specified output stream.if( !pManager->WriteRecord( *this, dwOutStream, &szRecord ) ) { // This is the end-of-file on this output stream. break; } ++dwRecCount; } return( _RC_SUCCESS_ );} |
void CStageManager::SeverInStream( _in CProcess &a_Process, _in DWORD a_dwInStream ); |
|
● |
Purpose Use SeverInStream() to disconnect the specified input
stream a_dwInStream. SeverInStream() disconnects both the specified input
stream a_dwInStream and the corresponding
output stream of the stage connected to the write-end of the stream. If it is
suspended; the stage connected to the write-end of the stream is released
from its suspended state and the stage regains control immediately. Any
subsequent write request made on the write-end of the stream will return an
end-of-file condition. Where you
place the SeverInStream() function in your stage is extremely important; it
can have a significant effect on how a pipeline behaves. Your stage must be able
to anticipate the effect it may have when it disconnects an input stream and
forces an end-of-file to propagate backward through a multi-stream pipeline.
|
||||
|
● |
Parameters |
||||
|
|
|
||||
|
● |
Returns
|
||||
|
● |
Messages None |
||||
|
● |
Usage To disconnect
an input stream: DWORD CMyStage::Go( void ) { // Access the manager.CStageManager *pManager = Manager(); // Access my stage. CStage *pStage = pManager->GetStage( *this ); ... // My stage reads only the first 100 input stream records from its // primary input stream. The stage then disconnects its primary // input stream and begins reading records from its secondary input // stream and writes them to its primary output stream. // The source input stream is initially the primary input stream. DWORD dwInStream = 0; // Record buffer. CString szRecord; // Accumulate the number of input records read. DWORD dwRecCount = 0; while( true ) { // Read a record from the specified input stream.if( !pManager->ReadRecord( *this, dwInStream, &szRecord ) ) { // This is the end-of-file on this input stream. break; } if( dwRecCount == 100 ) { pManager->SeverInStream( 0 ); // Switch to my secondary input stream. dwInStream = 1; } // Write the record to my primary output stream.if( !pManager->WriteRecord( *this, 0, &szRecord ) ) { // This is the end-of-file on my primary output stream. break; } ++dwRecCount; } return( _RC_SUCCESS_ );} |
bool CStageManager::ParseForToken( _inout CToken *a_pToken ); |
|
● |
Purpose Use ParseForToken() to extract the next token or
delimited phrase from your stage command argument. ParseForToken()
uses the CToken class
object to extract a token or delimited phrase from your stage command
argument. The ParseForToken() function, which can skip leading and trailing
delimiters; extracts the token or phrase and stores it at the address
specified in the CToken member m_pszTarget. |
||
|
● |
Parameters |
||
|
|
|
||
|
● |
Returns |
||
|
|
|
||
|
● |
Messages None |
||
|
● |
Usage The following example shows an edited excerpt from the CBetween
stage class commands’ Initialise() function. The portion of code shown;
illustrates how the ParseForToken() function is used to extract a stage
command keyword. bool CBetween::Initialise( void ) {
//
Access the manager. CStageManager *pManager
= Manager(); //
Access my stage. CStage *pStage =
pManager->GetStage( *this ); ... // Access my argument. const char *pszArgument = pStage->Argument(); CString szToken;CToken *pToken = new CToken( *this ); CCharacterString *pCharacterString = new CCharacterString( *this ); // Extract the first token and check if it is a keyword. pToken->m_pszSource = &pszArgument; pToken->m_pszTarget = &szToken; if( !pManager->ParseForToken( pToken ) ) { pManager->StageMessage( *this, 19, _ERROR_ ); return( false ); } ... // Extract the 'from' string.pCharacterString->m_pszSource = &pszArgument; pCharacterString->m_pszTarget = &m_szFrom; pCharacterString->m_bRequired = true; if( m_dwFromType == m_eString )pCharacterString->m_bNull = true; else pCharacterString->m_bNull = false;if( !pManager->ParseForCharacterString( pCharacterString ) ) return( false ); ... // There must be more argument. if( !pManager->ParseForToken( m_pToken )) { pManager->StageMessage( *this, 19, _ERROR_ ); return( false ); } ... Return( true );} |
bool CStageManager::ParseForIntegerString( _inout CIntegerString *a_pIntString ); |
|
● |
Purpose Use ParseForIntegerString() to
extract an integer string from your stage command argument. ParseForIntegerString()
uses the CIntegerString
class object to extract an integer string from your stage command argument.
The ParseForIntegerString() function, which can skip leading and trailing
delimiters, extracts and validates the format of the string and stores it at
the address specified in the CIntegerString member m_pszTarget. |
||||||||||
|
● |
Parameters |
||||||||||
|
|
|
||||||||||
|
● |
Returns |
||||||||||
|
|
|
||||||||||
|
● |
Messages When the CIntegerString member m_bRequired
is set to true and the argument is
missing or invalid; ParseForIntegerString() will issue one of the following
stage messages: 9, 20, 21, 60, 61. |
||||||||||
|
● |
Usage The following example shows an edited excerpt from the
CDuplicate stage class commands’ Initialise() function. The portion of code
shown; illustrates how the ParseForIntegerString() function is used to extract
an integer string from your stage command argument. bool CDuplicate::Initialise( void ){
//
Access the manager. CStageManager
*pManager = Manager(); //
Access my stage. CStage *pStage =
pManager->GetStage( *this ); ... // Access my argument. const char *pszArgument = pStage->Argument(); // Set defaults. m_lCopies = 1; ... if( *pszArgument ) { CString szToken;CToken *pToken = new CToken( *this ); CIntegerString *pIntegerString = new CIntegerString( *this ); pIntegerString->m_pszSource = &pszArgument;pIntegerString->m_pszTarget = &szToken; pIntegerString->m_dwMinUnsignedValue = 0; pIntegerString->m_dwMaxUnsignedValue = _MAX_INT_ - 1; // Try to extract an integer string. if( pManager->ParseForIntegerString( pIntegerString ) ) {pIntegerString->m_bRequired = true; if( !pManager->ConvertToInteger( pIntegerString ) ) return( false );m_lCopies = pIntegerString->m_lResult; } else { ... } // There should be no other arguments. if( *pszArgument ) {pManager->StageMessage( *this, 33, _ERROR_, pszArgument ); return( false ); } } ... return( true );} |
bool CStageManager::ParseForDoubleString( _inout CDoubleString *a_pDblString ); |
|
● |
Purpose Use ParseForDoubleString() to
extract a double string from your stage command argument. ParseForDoubleString()
uses the CDoubleString
class object to extract a double string from your stage command argument. The
ParseForDoubleString() function, which can skip leading and trailing
delimiters, extracts and validates the format of the string and stores it at
the address specified in the CDoubleString member m_pszTarget. |
||||||||||
|
● |
Parameters |
||||||||||
|
|
|
||||||||||
|
● |
Returns |
||||||||||
|
|
|
||||||||||
|
● |
Messages When the CDoubleString member m_bRequired
is set to true and the argument is
missing or invalid; ParseForDoubleString() will issue one of the following
stage messages: 31, 32. |
||||||||||
|
● |
Usage The following example shows how you might use the
ParseForDoubleString() function to extract a double string from your stage
command argument and convert it to a double-precision floating-point value. bool CMyStage:Initialise( void ){// Access the manager. CStageManager *pManager = Manager();// Access my stage. CStage *pStage = pManager->GetStage( *this ); ... // Access my argument. const char *pszArgument = pStage->Argument(); CString szToken;CToken *pToken = new CToken( *this ); if( *pszArgument ) { ... CDoubleString *pDoubleString = new CdoubleString( *this ); // Extract a double string. pDoubleString->m_pszSource = &pszArgument;pDoubleString->m_pszTarget = &szToken; pDoubleString->m_bRequired = true; if( m_pManager->ParseForDoubleString( m_pDoubleString ) ) { // Covert the string to a double-precision floating-point value.if( !m_pManager->ConvertToDouble( m_pDoubleString ) ) return( false );m_dbValue = m_pDoubleString->m_dbResult; } else return( false ); ... } ... Return( true );} |
bool CStageManager::ParseForCharacterString( _inout CCharacterString *a_pCharString ); |
|
● |
Purpose Use ParseForCharacterString() to
extract a delimited literal character string, hexadecimal string or binary
string from your stage command argument. ParseForCharacterString()
uses the CCharacterString class object to
extract the string from your stage command argument. The
ParseForCharacterString() function, which can skip leading and trailing
delimiters; extracts the string, converts it to an ASCII character value and
stores the result at the address specified in the CCharacterString member m_pszTarget. |
||||||||||||||||||||||||||||||
|
● |
Parameters |
||||||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||||
|
● |
Returns |
||||||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||||
|
● |
Messages When the CCharacterString member m_bRequired
is set to true and the argument is
missing or invalid; ParseForCharacterString() will issue one of the following
stage messages: 12, 15, 17, 19, 22, 23, 37, 38, 39, 40, 43, 50. |
||||||||||||||||||||||||||||||
|
● |
Usage The following example shows an
edited excerpt from the CLiteral stage class commands’ Initialise() function.
The portion of code shown; illustrates how the ParseForCharacterString()
function is used to extract a delimited character string, hexadecimal string
or binary string from your stage command argument. bool CLiteral::Initialise( void ) {// Access the manager. CStageManager *pManager = Manager();// Access my stage. CStage *pStage = pManager->GetStage( *this ); ... // Access my argument. const char *pszArgument = m_pStage->Argument(); // Set the default. CString szLiteral = ""; if( *pszArgument ) { ... if( *pszArgument ) {CCharacterString *pCharacterString = new CCharacterString( *this ); pCharacterString->m_bRequired = false; pCharacterString->m_pszSource = &pszArgument; pCharacterString->m_pszTarget = &szLiteral; pCharacterString->m_bNull = true; // If we cannot extract a character string, then the argument must be // a character range. if( !pManager->ParseForCharacterString( pCharacterString ) ) {CCharacterRange *pCharacterRange = new CCharacterRange( *this ); pCharacterRange->m_pszSource = &pszArgument; pCharacterRange->m_bRequired = true; pCharacterRange->m_bSkipTrailing = true; // Extract an expanded character range.pCharacterRange->m_bExpand = true; pCharacterRange->m_pszExpandedRange = &szLiteral; if( !pManager->ParseForCharacterRange( pCharacterRange ) ) return( false ); } } // There should be no other arguments. if( *pszArgument ) {m_pManager->StageMessage( *this, 33, _ERROR_, pszArgument ); return( false ); } } return( true );} |
bool CStageManager::ParseForRegExp( _in CProcess &a_Process, _inout CRegExpression *a_pRegExp, _in_opt bool a_bCaseSensitive = true ); |
|
● |
Purpose Use ParseForRegExp() to validate and assign a
regular expression that has been extracted from your stage command argument. During the initialisation phase of your stage; in or via a call
from your stages’ Initialise() function; you extract the delimited character
string which specifies the regular expression definition; using the ParseForCharacterString() function. Next, you
present the buffer which contains that string to the ParseForRegExp()
function; which will parse, evaluate and assign the expression. Then, during
the runtime phase of your stage; in or via a call from your stages’ Go() function; you apply that expression to your stage
input records; through a call to the RegExpMatch() function. |
||||||
|
● |
Parameters |
||||||
|
|
|
||||||
|
● |
Returns |
||||||
|
|
|
||||||
|
● |
Messages When an error occurs parsing the
regular expression; ParseForRegExp() will issue the following stage message: 18. |
||||||
|
● |
Usage The following example shows
edited excerpts from the CBetween stage class definition and its stage class
functions: Initialise() and Go(). The Initialise() function illustrates how you
might extract a regular expression from your stage command argument and the
Go() function demonstrates how you might implement regular expression
processing on your input records. // Class definition class CBetween : public CProcess { ... CStageManager *m_pManager; CStage *m_pStage; CString m_szRecord; DWORD m_dwFromType;CRegExpression *m_pFromRegExp; CString m_szFrom; enum m_eType { ..., m_eRegExp }; ...};// Initialisation phase.bool CBetween::Initialise( void ) { // Access the manager. m_pManager = Manager(); // Access my stage. m_pStage = m_pManager->GetStage( *this ); // Access my argument. const char *pszArgument = m_pStage->Argument(); // Perform any preprocessing required. if( !m_pManager->PreProcess( *this, &pszArgument ) )return( false ); ...CCharacterString *pCharacterString = new CCharacterString( *this ); // Extract the 'from' string. pCharacterString->m_pszSource = &pszArgument; pCharacterString->m_pszTarget = &m_szFrom; pCharacterString->m_bRequired = true; if( m_dwFromType == m_eString ) pCharacterString->m_bNull = true; else pCharacterString->m_bNull = false;if( !m_pManager->ParseForCharacterString( pCharacterString ) ) return( false ); ... // Perform the regular expression validation. if( m_dwFromType == m_eRegExp ) ) { m_pFromRegExp->m_RegExp.Expression = m_szFrom; if( !m_pManager->ParseForRegExp( *this, m_pFromRegExp, !m_pStage->Casei() ) ) return( false ); } ... return( true );}// Runtime phase.DWORD CBetween::Go( void ){ ... // Ok, now lets read and process the primary input stream. for( ;; ) { // If all my output streams are disconnected, then exit. if( !m_pStage->OutStreamsConnected() ) break;if( !m_pManager->PeekRecord( *this, 0, &m_szRecord ) ) break; ... else if( m_dwFromType == m_eRegExp ) {if( m_pManager->RegExpMatch( m_pFromRegExp, m_szRecord ) ) { ... } } ... // Write record to designated output sstream. m_pManager->WriteRecord( *this, dwStream, &m_szRecord ); // Release the stage that we read from.m_pManager->ConsumeRecord( *this, 0 ); } return( _RC_SUCCESS_ );} |
bool CStageManager::ParseForIntegerRange( _inout CIntegerRange *a_pIntRange ); |
|
● |
Purpose Use ParseForIntegerRange() to
extract an integer range from your stage command argument. ParseForIntegerRange() uses the CIntegerRange class
object to extract an integer range from your stage command argument. The
ParseForIntegerRange() function, which can skip leading and trailing
delimiters, extracts the; from and to range values and stores them; as real
integer values in the CIntegerString members m_lFrom and m_lTo,
respectively. To use the function; simply set
the member m_nType
to one of the following values:
By default;
ParseForIntegerRange() sets the starting column m_lFrom to the unsigned integer value of 1 and the ending column m_lTo to the unsigned integer value of
_MAX_INT_. There are two types of integer
range; the first is a range which describes an input; a range of columns,
words or fields of an input record on which to operate, and the second; which
describes an output column position and range length; a starting and
corresponding length of some piece of data to write to an output record. The following definitions
describe the possible patterns and their relative types:
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
● |
Parameters |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
● |
Returns |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
● |
Messages When the CIntegerRange member m_bRequired
is set to true and the argument is
missing or invalid; ParseForIntegerRange() will issue one of the following
stage messages: 4, 5, 9, 15, 20, 24, 25, 46, 51, 52, 60, 61, 62. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
● |
Usage The following example shows an
edited excerpt from the CSort stage class commands’ Initialise() function.
The portion of code shown; illustrates how the ParseForIntegerRange()
function is used to extract an integer range from your stage command
argument. bool CSort::Initialise( void ){// Access the manager. CStageManager *pManager = Manager();// Access my stage. CStage *pStage = pManager->GetStage( *this ); ... // Access my argument. const char *pszArgument = m_pStage->Argument(); if( *pszArgument ) {CIntegerRange *pIntegerRange = new CIntegerRange( *this ); ...pIntegerRange->m_pszSource = &pszArgument; pIntegerRange->m_bFromSigned = false; pIntegerRange->m_bToSigned = false; pIntegerRange->m_bRequired = true; // Loop through the groups that are defined. for( DWORD dwCount = 0; dwCount < _MAX_INT_; ++dwCount ) { // If its the end of the argument.. if( !*pszArgument ) break; if( !m_pManager->ParseForIntegerRange( pIntegerRange ) ) return( false ); ... } } ... return( true );} |
bool CStageManager::ParseForCharacter( _inout CCharacterString *a_pCharString ); |
|
● |
Purpose Use ParseForCharacter() to
extract an ASCII character, hexadecimal character or binary character from
your stage command argument. ParseForCharacter()
uses the CCharacterString class object to
extract a character definition from your stage command argument. The
ParseForCharacter() function, which can skip leading and trailing delimiters;
extracts the character definition and stores it as an ASCII character at the
address specified in the CCharacterString member m_pszTarget. |
||||||||||||||||||||||||||
|
● |
Parameters |
||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||
|
● |
Returns |
||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||
|
● |
Messages When the CCharacterString member m_bRequired
is set to true and the argument is
missing or invalid; ParseForCharacter() will issue one of the following stage
messages: 12, 15, 35, 37, 38, 39, 40, 43, 47, 48, 50 |
||||||||||||||||||||||||||
|
● |
Usage The following example shows an
edited excerpt from the CPad stage class commands’ Initialise() function. The
portion of code shown; illustrates how the ParseForCharacter() function is
used to extract a character from your stage command argument. bool CPad::Initialise( void ) { // Access the manager.m_pManager = Manager(); // Access my stage.m_pStage = m_pManager->GetStage( *this ); ... // Access my argument.const char *pszArgument = m_pStage->Argument(); // Set the default. m_szChars = " "; ... if( *pszArgument ) { // Save the current pointer. const char *pszSave = pszArgument; // Extract the next token. m_pToken->m_pszSource = &pszArgument; m_pToken->m_pszTarget = &szToken;if( !m_pManager->ParseForToken( m_pToken ) ) return( false ); if( szToken.CompareNoCase( "SPACE" ) ) { // Restore the pointer. pszArgument = pszSave; // Extract the pad character. m_pCharacterString->m_pszSource = &pszArgument; m_pCharacterString->m_pszTarget = &m_szChars; m_pCharacterString->m_bRequired = true; if( !m_pManager->ParseForCharacter( m_pCharacterString ) ) return( false ); } // There should be no other arguments. if( *pszArgument ) {m_pManager->StageMessage( *this, 33, _ERROR_, pszArgument ); return( false ); } } return( true );} |
bool CStageManager::ParseForCharacterRange( _inout CCharacterRange *a_pCharRange ); |
|
● |
Purpose Use ParseForCharacterRange() to extract an ASCII
character range, hexadecimal character range or binary character range from
your stage command argument. ParseForCharacterRange() uses the CCharacterRange class object to
extract a character range from your stage command argument. The
ParseForCharacterRange() function, which can skip leading and trailing
delimiters, extracts the; from and to range values and stores them in the
CCharacterRange members m_szFrom
and m_szTo,
respectively. The following definitions describe the possible patterns
and their relative types:
When you set the CCharacterRange member m_bExpand to true; ParseForCharacterRange()
will fill the buffer pointed to by the member m_pszExpandedRange
with an expanded version of the range. That is to say; if the stage command
argument comprises the character range: A-G, the buffer will contain the
expanded string: ABCDEFG. |
||||||||||||||||||
|
● |
Parameters |
||||||||||||||||||
|
|
|
||||||||||||||||||
|
● |
Returns |
||||||||||||||||||
|
|
|
||||||||||||||||||
|
● |
Messages When the CCharacterRange member m_bRequired
is set to true and the argument is
missing or invalid; ParseForIntegerRange() will issue one of the following
stage messages: 9, 12, 20, 35, 40, 47, 48, 50, 60, 61. |
||||||||||||||||||
|
● |
Usage The following example shows an
edited excerpt from the CLiteral stage class commands’ Initialise() function.
The portion of code shown; illustrates how the ParseForCharacterRange()
function is used to extract a character range from your stage command
argument. bool CLiteral::Initialise( void ) { // Access the manager. CStageManager *pManager = Manager();// Access my stage. CStage *pStage = pManager->GetStage( *this ); ... // Access my argument. const char *pszArgument = m_pStage->Argument();
// Set the default. CString szLiteral = ""; if( *pszArgument ) { ... if( *pszArgument ) { CCharacterString *pCharacterString = new CCharacterString( *this ); pCharacterString->m_bRequired = false; pCharacterString->m_pszSource = &pszArgument; pCharacterString->m_pszTarget = &szLiteral; pCharacterString->m_bNull = true; // If we cannot extract a
character string, then the argument must be // a character range. if(
!pManager->ParseForCharacterString( pCharacterString ) ) { CCharacterRange *pCharacterRange = new CCharacterRange( *this ); pCharacterRange->m_pszSource = &pszArgument; pCharacterRange->m_bRequired = true; pCharacterRange->m_bSkipTrailing = true; // Extract an expanded
character range. pCharacterRange->m_bExpand = true; pCharacterRange->m_pszExpandedRange = &szLiteral; if(
!pManager->ParseForCharacterRange( pCharacterRange ) ) return( false ); } }
// There should be no other arguments. if( *pszArgument ) { m_pManager->StageMessage( *this, 33, _ERROR_, pszArgument ); return( false ); } } return( true ); } |
bool CStageManager::ConvertToInteger( _inout CIntegerString *a_pIntString ); |
|
● |
Purpose Use ConvertToInteger() to convert an integer string to a
(long) integer value. ConvertToInteger() validates and converts the integer
string contained in the CIntegerString member m_pszTarget
to a (long) integer value and stores that result in the CIntegerString member
m_lResult. |
||||||||||
|
● |
Parameters |
||||||||||
|
|
|
||||||||||
|
● |
Returns |
||||||||||
|
|
|
||||||||||
|
● |
Messages When the CIntegerString member m_bRequired
is set to true and the argument is
invalid; ConvertToInteger() will issue one of the following stage messages: 24, 51, 52, 62. |
||||||||||
|
● |
Usage The following example shows an edited excerpt from the
CDuplicate stage class commands’ Initialise() function. The portion of code
shown; illustrates how the ParseForIntegerString() and ConvertToInteger()
functions are used to extract an integer string from your stage command
argument and convert it to a real (long) integer value. bool CDuplicate::Initialise( void ){
//
Access the manager. CStageManager
*pManager = Manager(); //
Access my stage. CStage *pStage =
pManager->GetStage( *this ); ... // Access my argument. const char *pszArgument = pStage->Argument(); // Set defaults. m_lCopies = 1; ... if( *pszArgument ) { CString szToken;CToken *pToken = new CToken( *this ); CIntegerString *pIntegerString = new CIntegerString( *this ); pIntegerString->m_pszSource = &pszArgument;pIntegerString->m_pszTarget = &szToken; pIntegerString->m_dwMinUnsignedValue = 0; pIntegerString->m_dwMaxUnsignedValue = _MAX_INT_ - 1; // Try to extract an integer string.if( pManager->ParseForIntegerString( pIntegerString ) ) {pIntegerString->m_bRequired = true; if( !pManager->ConvertToInteger( pIntegerString ) ) return( false );m_lCopies = pIntegerString->m_lResult; } else { ... } // There should be no other arguments. if( *pszArgument ) {pManager->StageMessage( *this, 33, _ERROR_, pszArgument ); return( false ); } } ... return( true );
} |
bool CStageManager::ConvertToDouble( _inout CDoubleString *a_pDblString ); |
|
● |
Purpose Use ConvertToDouble() to convert a double string to a
double-precision floating-point value. ConvertToDouble() validates and converts the double
string contained in the CDoubleString member m_pszTarget
to a double-precision floating-point value and stores that result in the
CDoubleString member m_dbResult. |
||||||||||
|
● |
Parameters |
||||||||||
|
|
|
||||||||||
|
● |
Returns |
||||||||||
|
|
|
||||||||||
|
● |
Messages When the CDoubleString member m_bRequired
is set to true and the argument is
invalid; ConvertToDouble() will issue one of the following stage messages: 32, 42. |
||||||||||
|
● |
Usage The following example shows how you might use the
ConvertToDouble() function to convert it to a double-precision floating-point
value. bool CMyStage:Initialise( void ){// Access the manager. CStageManager *pManager = Manager();// Access my stage. CStage *pStage = pManager->GetStage( *this ); ... // Access my argument. const char *pszArgument = pStage->Argument(); CString szToken;CToken *pToken = new CToken( *this ); if( *pszArgument ) { ... CDoubleString *pDoubleString = new CdoubleString( *this ); // Extract a double string. pDoubleString->m_pszSource = &pszArgument;pDoubleString->m_pszTarget = &szToken; pDoubleString->m_bRequired = true; if( m_pManager->ParseForDoubleString( m_pDoubleString ) ) { // Covert the string to a double-precision floating-point value.if( !m_pManager->ConvertToDouble( m_pDoubleString ) ) return( false );m_dbValue = m_pDoubleString->m_dbResult; } else return( false ); ... } ... Return( true );} |
void CStageManager::ExtractColumnRange( _inout CExtractRange *a_pRange ); |
|
● |
Purpose Use ExtractColumnRange() to
extract a column delimited substring from an input stream record. During the initialisation phase
of your stage; in or via a call from your stages’ Initialise() function; you first make a call to
the ParseForIntegerRange()
function to extract an integer range definition from your stage command
argument. This range defines the columns that you want to extract from each
input stream record during your runtime phase. Next, you pre-fill the CExtractRange class object with
the values contained in the CIntegerString
class object. Finally during your runtime phase, in or via call from your
stages’ Go()
function; you make a call to the ExtractColumnRange() function to determine
the starting m_lFrom and ending m_lTo columns of the specified column
range. ExtractFieldRange() extracts the
substring which starts at column number m_lFrom, up to and including
column number m_lTo and stores the
extracted string in the buffer pointed to by the member m_pszTarget. |
||
|
● |
Parameters |
||
|
|
|
||
|
● |
Returns
|
||
|
● |
Messages None |
||
|
● |
Usage The following example shows a simplified version of the CTranslate
stage commands’ Go() function. The code illustrates how the
ExtractColumnRange() function can be used to isolate and extract a range of
columns from an input stream record. DWORD CTranslate::Go( void ){ // Pre-load the range object with the common default values used by all three range types. CString szRange;CExtractRange *pRange = new CExtractRange; pRange->m_pszSource = &m_szRecord; pRange->m_pszTarget = &szRange; pRange->m_bExtractRange = false; pRange->m_bResolveRange = true; // Access my primary output stream. COutStream *pPriOutStream = m_pStage->GetOutStream( 0 ); // Ok, now lets read and process our input streams.. for( ;; ) { // If my primary output stream is disconnected, then exit.if( pPriOutStream->IsDisConnected() ) break;if( !m_pManager->PeekRecord( *this, 0, &m_szRecord ) ) break; // Apply the translate table to the record. // Extract the simple column range. if( m_bInpRange ) { pRange->m_lFrom = m_lFrom; pRange->m_lTo = m_lTo;m_pManager->ExtractColumnRange( pRange ); } else // Extract the field range. if( m_bInpField ) { pRange->m_szDelimiter = m_szFieldSeperator; pRange->m_lFrom = m_lFrom; pRange->m_lTo = m_lTo;m_pManager->ExtractFieldRange( pRange ); } else // Extract the word range. if( m_bInpWord ) { pRange->m_szDelimiter = m_szWordSeperator; pRange->m_lFrom = m_lFrom; pRange->m_lTo = m_lTo;m_pManager->ExtractWordRange( pRange ); } // Using each byte of the record as an index into the translate table; replace that byte with the // corresponding translate table entry. if( pRange->m_lFrom >= 0 && pRange->m_lFrom <= m_szRecord.GetLength() ) { const char *pszRecord = ( LPCTSTR )m_szRecord + pRange->m_lFrom; for( int nIndex = pRange->m_lFrom; nIndex <= pRange->m_lTo && *pszRecord; ++nIndex, ++pszRecord ) m_szRecord.SetAt( nIndex, m_szTransTable.GetAt( ( BYTE )( *pszRecord ) - 1 ) ); } // Write the record to the primary output stream.if( !m_pManager->WriteRecord *this, 0, &m_szRecord ) ) break; // Release the stage that we read from.m_pManager->ConsumeRecord( *this, 0 ); } // Release the allocation. delete pRange; return( _RC_SUCCESS_ );} |
void CStageManager::ExtractWordRange( _inout CExtractRange *a_pRange ); |
|
● |
Purpose Use ExtractWordRange() to extract
a word delimited substring from an input stream record. During the initialisation phase
of your stage; in or via a call from your stages’ Initialise() function; you first make a call to
the ParseForIntegerRange()
function to extract an integer range definition from your stage command
argument. This range defines the words that you want to extract from each
input stream record during your runtime phase. Next, you pre-fill the CExtractRange class object with
the values contained in the CIntegerString
class object. Finally during your runtime phase, in or via call from your
stages’ Go()
function; you make a call to the ExtractWordRange() function to determine the
starting m_lFrom and ending m_lTo columns of the specified word
range. ExtractWordRange() extracts the
substring which starts at word number m_lFrom, up to and including
word number m_lTo and stores the
extracted string in the buffer pointed to by the member m_pszTarget. |
||
|
● |
Parameters |
||
|
|
|
||
|
● |
Returns
|
||
|
● |
Messages None |
||
|
● |
Usage The following example shows a simplified version of the CTranslate
stage commands’ Go() function. The code illustrates how the
ExtractWordRange() function can be used to isolate and extract a range of
words from an input stream record. DWORD CTranslate::Go( void ){ // Pre-load the range object with the common default values used by all three range types. CString szRange;CExtractRange *pRange = new CExtractRange; pRange->m_pszSource = &m_szRecord; pRange->m_pszTarget = &szRange; pRange->m_bExtractRange = false; pRange->m_bResolveRange = true; // Access my primary output stream. COutStream *pPriOutStream = m_pStage->GetOutStream( 0 ); // Ok, now lets read and process our input streams.. for( ;; ) { // If my primary output stream is disconnected, then exit.if( pPriOutStream->IsDisConnected() ) break;if( !m_pManager->PeekRecord( *this, 0, &m_szRecord ) ) break; // Apply the translate table to the record. // Extract the simple column range. if( m_bInpRange ) { pRange->m_lFrom = m_lFrom; pRange->m_lTo = m_lTo;m_pManager->ExtractColumnRange( pRange ); } else // Extract the field range. if( m_bInpField ) { pRange->m_szDelimiter = m_szFieldSeperator; pRange->m_lFrom = m_lFrom; pRange->m_lTo = m_lTo;m_pManager->ExtractFieldRange( pRange ); } else // Extract the word range. if( m_bInpWord ) { pRange->m_szDelimiter = m_szWordSeperator; pRange->m_lFrom = m_lFrom; pRange->m_lTo = m_lTo;m_pManager->ExtractWordRange( pRange ); } // Using each byte of the record as an index into the translate table; replace that byte with the // corresponding translate table entry. if( pRange->m_lFrom >= 0 && pRange->m_lFrom <= m_szRecord.GetLength() ) { const char *pszRecord = ( LPCTSTR )m_szRecord + pRange->m_lFrom; for( int nIndex = pRange->m_lFrom; nIndex <= pRange->m_lTo && *pszRecord; ++nIndex, ++pszRecord ) m_szRecord.SetAt( nIndex, m_szTransTable.GetAt( ( BYTE )( *pszRecord ) - 1 ) ); } // Write the record to the primary output stream.if( !m_pManager->WriteRecord *this, 0, &m_szRecord ) ) break; // Release the stage that we read from.m_pManager->ConsumeRecord( *this, 0 ); } // Release the allocation. delete pRange; return( _RC_SUCCESS_ );} |
void CStageManager::ExtractFieldRange( _inout CExtractRange *a_pRange ); |
|
● |
Purpose Use ExtractFieldRange() to extract
a field delimited substring from an input stream record. During the initialisation phase
of your stage; in or via a call from your stages’ Initialise() function; you first make a call to
the ParseForIntegerRange()
function to extract an integer range definition from your stage command
argument. This range defines the fields that you want to extract from each
input stream record during your runtime phase. Next, you pre-fill the CExtractRange class object with
the values contained in the CIntegerString
class object. Finally during your runtime phase, in or via call from your
stages’ Go()
function; you make a call to the ExtractFieldRange() function to determine
the starting m_lFrom and ending m_lTo columns of the specified field
range. ExtractFieldRange() extracts the
substring which starts at field number m_lFrom, up to and including
field number m_lTo and stores the
extracted string in the buffer pointed to by the member m_pszTarget. |
||
|
● |
Parameters |
||
|
|
|
||
|
● |
Returns
|
||
|
● |
Messages None |
||
|
● |
Usage The following example shows a simplified version of the
CTranslate stage commands’ Go() function. The code illustrates how the ExtractFieldRange()
function can be used to isolate and extract a range of fields from an input
stream record. DWORD CTranslate::Go( void ){ // Pre-load the range object with the common default values used by all three range types. CString szRange;CExtractRange *pRange = new CExtractRange; pRange->m_pszSource = &m_szRecord; pRange->m_pszTarget = &szRange; pRange->m_bExtractRange = false; pRange->m_bResolveRange = true; // Access my primary output stream. COutStream *pPriOutStream = m_pStage->GetOutStream( 0 ); // Ok, now lets read and process our input streams.. for( ;; ) { // If my primary output stream is disconnected, then exit.if( pPriOutStream->IsDisConnected() ) break;if( !m_pManager->PeekRecord( *this, 0, &m_szRecord ) ) break; // Apply the translate table to the record. // Extract the simple column range. if( m_bInpRange ) { pRange->m_lFrom = m_lFrom; pRange->m_lTo = m_lTo;m_pManager->ExtractColumnRange( pRange ); } else // Extract the field range. if( m_bInpField ) { pRange->m_szDelimiter = m_szFieldSeperator; pRange->m_lFrom = m_lFrom; pRange->m_lTo = m_lTo; m_pManager->ExtractFieldRange( pRange ); } else // Extract the word range. if( m_bInpWord ) { pRange->m_szDelimiter = m_szWordSeperator; pRange->m_lFrom = m_lFrom; pRange->m_lTo = m_lTo;m_pManager->ExtractWordRange( pRange ); } // Using each byte of the record as an index into the translate table; replace that byte with the // corresponding translate table entry. if( pRange->m_lFrom >= 0 && pRange->m_lFrom <= m_szRecord.GetLength() ) { const char *pszRecord = ( LPCTSTR )m_szRecord + pRange->m_lFrom; for( int nIndex = pRange->m_lFrom; nIndex <= pRange->m_lTo && *pszRecord; ++nIndex, ++pszRecord ) m_szRecord.SetAt( nIndex, m_szTransTable.GetAt( ( BYTE )( *pszRecord ) - 1 ) ); } // Write the record to the primary output stream.if( !m_pManager->WriteRecord *this, 0, &m_szRecord ) ) break; // Release the stage that we read from.m_pManager->ConsumeRecord( *this, 0 ); } // Release the allocation. delete pRange; return( _RC_SUCCESS_ );} |
bool RegExpMatch( _in CRegExpression *a_pRegExp,_in CString &a_szSource ); |
|
● |
Purpose Use RegExpMatch() to compare a regular expression against
the contents of the specified buffer a_szSource. During the initialisation phase of your stage; in or via a call
from your stages’ Initialise() function; you extract the delimited character
string which specifies the regular expression definition; using the ParseForCharacterString() function. Next, you
present the buffer which contains that string to the ParseForRegExp() function; which will
parse, evaluate and assign the expression. Then, during the runtime phase of
your stage; in or via a call from your stages’ Go() function; you apply that expression to your stage
input records; through a call to the RegExpMatch() function. |
||||
|
● |
Parameters |
||||
|
|
|
||||
|
● |
Returns
|
||||
|
● |
Messages None |
||||
|
● |
Usage The following example shows
edited excerpts from the CBetween stage class definition and its stage class functions:
Initialise() and Go(). The Initialise() function illustrates how you might
extract a regular expression from your stage command argument and the Go()
function demonstrates how you might implement regular expression processing
on your input records. // Class definition class CBetween : public CProcess { ... CStageManager *m_pManager; CStage *m_pStage; CString m_szRecord; DWORD m_dwFromType;CRegExpression *m_pFromRegExp; CString m_szFrom; enum m_eType { ..., m_eRegExp }; ...};// Initialisation phase.bool CBetween::Initialise( void ) { // Access the manager. m_pManager = Manager(); // Access my stage. m_pStage = m_pManager->GetStage( *this ); // Access my argument. const char *pszArgument = m_pStage->Argument(); // Perform any preprocessing required. if( !m_pManager->PreProcess( *this, &pszArgument ) ) return( false ); ...CCharacterString *pCharacterString = new CCharacterString( *this ); // Extract the 'from' string. pCharacterString->m_pszSource = &pszArgument; pCharacterString->m_pszTarget = &m_szFrom; pCharacterString->m_bRequired = true; if( m_dwFromType == m_eString ) pCharacterString->m_bNull = true; else pCharacterString->m_bNull = false;if( !m_pManager->ParseForCharacterString( pCharacterString ) ) return( false ); ... // Perform the regular expression validation. if( m_dwFromType == m_eRegExp ) ) { m_pFromRegExp->m_RegExp.Expression = m_szFrom;if( !m_pManager->ParseForRegExp( *this, m_pFromRegExp, !m_pStage->Casei() ) ) return( false ); } ... return( true );}// Runtime phase.DWORD CBetween::Go( void ){ ... // Ok, now lets read and process the primary input stream. for( ;; ) { // If all my output streams are disconnected, then exit. if( !m_pStage->OutStreamsConnected() ) break;if( !m_pManager->PeekRecord( *this, 0, &m_szRecord ) ) break; ... else if( m_dwFromType == m_eRegExp ) { if( m_pManager->RegExpMatch( m_pFromRegExp, m_szRecord ) ) { ... } } ... // Write record to designated output sstream. m_pManager->WriteRecord( *this, dwStream, &m_szRecord ); // Release the stage that we read from.m_pManager->ConsumeRecord( *this, 0 ); } return( _RC_SUCCESS_ );} |
bool PatternMatch(_in const char *a_pszPattern, _in const char *a_pszSource ); |
|
● |
Purpose Use PatternMatch() to compare a pattern of characters against
the contents of the specified buffer a_pszSource. The pattern consists of a sequence of characters; any which
may be the wildcard characters; ? and *. Where ? represents any single
matching character and * represents any one or more matching characters. |
||||
|
● |
Parameters |
||||
|
|
|
||||
|
● |
Returns
|
||||
|
● |
Messages None |
||||
|
● |
Usage The following example shows an edited excerpt from the
CTolabel stage class commands’ Go() function. The portion of code shown;
illustrates how you can compare the contents of an input record with a user
defined pattern. DWORD CTolabel::Go( void ){ ... bool bFound = false; DWORD dwStream = 0; // Ok, now lets read and process our input streams.. for( ;; ) { // If all my output streams are disconnected, then exit.if( !m_pStage->OutStreamsConnected() ) break;if( !m_pManager->PeekRecord( *this, 0, &m_szRecord ) ) { // If the label has not yet been found, perform the search. if( !bFound ) { ... else if( m_dwType == m_ePattern ) { if( m_pManager->PatternMatch( m_szLabel, m_szRecord ) ) { bFound = true; dwStream = 1; } } else if( m_dwType == m_eRegExp ) {if( m_pManager->RegExpMatch( m_pRegExp, m_szRecord ) ) { bFound = true; dwStream = 1; } } } // Write the record to the given output stream. if( !m_pManager->WriteRecord( *this, dwStream, &m_szRecord ) && dwStream ) break; // Release the stage that we read from.m_pManager->ConsumeRecord( *this, 0 ); } } return( _RC_SUCCESS_ );} |
bool CStageManager::SetStatus( _inout CStageInitInfo *a_pInfo ); |
|
● |
Purpose Use SetStatus() to inform the StageManager of the success
or failure of your stage initialisation phase. SetStatus() is the function through which your stage informs
the StageManager of the success or failure of your stages’ initialisation
phase; by setting a value of true
or false in the CStageInitInfo
member m_bReturnCode.
The function causes your stage to become suspended until the StageManager has
received and inspected this initialisation phase return code from all of the
stages in the pipeline. If any stage reports a failed initialisation; the
StageManager passes back a value of false,
indicating that your stage should terminate immediately; otherwise it returns
a value of true indicating that
your stage should continue onto its runtime phase. |
||
|
● |
Parameters |
||
|
|
|
||
|
● |
Returns |
||
|
|
|
||
|
● |
Messages None |
||
|
● |
Usage DWORD BeginStage( CStageInitInfo *a_pInfo ) { AFX_MANAGE_STATE(
AfxGetStaticModuleState() ); //
Instantiate the CStage class object. CLookup lookup(
a_pInfo ); //
Perform initialisation phase processing. a_pInfo->m_bReturnCode = lookup.Initialise(); // Inform the manager of the initialisation phase result and if // this or any other stage has reported an error, then terminate processing.
if( !a_pInfo->Manager()->SetStatus(
a_pInfo ) ) return( _RC_FAIL_ ); // Otherwise; proceed to our runtime
phase. return( lookup.Go() ); } |
RexxExitContext *CStageManager::GetRexxExitContext( void ); |
|
● |
Purpose Use GetRexxExitContext() to get
the RexxExitContext object that references the instantiated ooRexx
environment launched by Pipelines. GetRexxExitContext() is the
function through which your stage accesses the services that are specific to
this ooRexx exit call, which includes; access to variables in the caller’s
variable context. In other words, in order to communicate with ooRexx and be
able to read from, write to, create and destroy ooRexx variables, stems and
arrays; you must first call this function to acquire an interface exit
object. |
||
|
● |
Parameters |
||
|
|
|
||
|
● |
Returns |
||
|
|
|
||
|
● |
Messages None |
||
|
● |
Usage The following example shows an edited excerpt from the
CStageManager class GetRexxArraySize() function. The portion of code shown;
illustrates how to acquire the ooRexx exit context in order to determine the
size of the array specified by the argument a_pszName. DWORD CStageManager::GetRexxArraySize( const char *a_pszName ){ DWORD dwSize = 0; RexxThreadContext *pThreadContext; // Through the exit context; obtain the ooRexx thread context. if( GetRexxExitContext()->threadContext->instance->AttachThread( &pThreadContext ) ) { CString szName = a_pszName; // Convert the name of the array to uppercase. CStringToUpper( &szName ); const char *pszName = szName; // Get a pointer to the directory that contains the array. RexxObjectPtr ObjPtr = pThreadContext->DirectoryAt( GetRexxDirectoryObject(), pszName ); if( ObjPtr != NULLOBJECT ) { CString szItem; // Ensure that it is indeed an array object. if( pThreadContext->IsArray( ObjPtr ) ) { // Get the size of the array RexxArrayObject arrayPtr = ( RexxArrayObject )ObjPtr; dwSize = ( DWORD ) pThreadContext->ArraySize( arrayPtr ); } } // Release the thread. pThreadContext->DetachThread(); } // Return the size of the array. return( dwSize );} |
RexxDirectoryObject CStageManager::GetRexxDirectoryObject( void ); |
|
● |
Purpose Use GetRexxtDirectoryObject() to access the ooRexx directory
object that contains all of the variables, stems and arrays that are
currently defined. |
||
|
● |
Parameters |
||
|
|
|
||
|
● |
Returns |
||
|
|
|
||
|
● |
Messages None |
||
|
● |
Usage The following example shows an edited excerpt from the
CStageManager class GetRexxArraySize() function. The portion of code shown;
illustrates how to access the ooRexx Directory Object that contains a copy of
all of the ooRexx variables that are currently defined; in order to determine
the size of the array specified by the argument a_pszName. DWORD CStageManager::GetRexxArraySize( const char *a_pszName ){ DWORD dwSize = 0; RexxThreadContext *pThreadContext; // Through the exit context; obtain the ooRexx thread context. if( GetRexxExitContext()->threadContext->instance->AttachThread( &pThreadContext ) ) { CString szName = a_pszName; // Convert the name of the array to uppercase. CStringToUpper( &szName ); const char *pszName = szName; // Get a pointer to the directory that contains the array. RexxObjectPtr ObjPtr = pThreadContext->DirectoryAt( GetRexxDirectoryObject(), pszName ); if( ObjPtr != NULLOBJECT ) { CString szItem; // Ensure that it is indeed an array object. if( pThreadContext->IsArray( ObjPtr ) ) { // Get the size of the array RexxArrayObject arrayPtr = ( RexxArrayObject )ObjPtr; dwSize = ( DWORD ) pThreadContext->ArraySize( arrayPtr ); } } // Release the thread. pThreadContext->DetachThread(); } // Return the size of the array. return( dwSize );
} |
|
DWORD
CStageManager::GetRexxVariable( _in
const char
*a_pszName, _out CString
*a_pszValue ); |
|
● |
Purpose Use GetRexxVariable() to obtain the value of the ooRexx
variable, specified by; a_pszName. GetRexxVariable() can be used to obtain the value of a
simple ooRexx variable, stem entry or array entry. In the case of a stem
entry; you must specify the name of the entry; with each index in that name
separated by a period (.), for example mystem.i.j.
In the case of an array entry; you must specify the name of the entry; with
each index in that name enclosed in square brackets ([]), for example myarray[i][j]. The function will
insert the value of the specified entry into the CString object pointed to by
a_pszValue. |
||||
|
● |
Parameters |
||||
|
|
|
||||
|
● |
Returns |
||||
|
|
|
||||
|
● |
Messages None |
||||
|
● |
Usage The
following snippet of code illustrates how to use the GetRexxVariable()
function. ... CString
szName = “MYVARIABLE”; CString
szValue; // Is the variable currently defined. dwRetCode
= m_pManager->GetRexxVariable( ( LPCTSTR )szName, &szValue ); if( dwRetCode == _RC_REXX_SUCCESS_ ) { ... } else return( false ); ... |
|
bool CStageManager::GetRexxStem( _in const char *a_pszName, _inout std::list< CString > *a_plStem ); |
|
● |
Purpose Use GetRexxStem() to obtain the contents of the ooRexx
stem, specified by; a_pszName. You must specify the name of the stem, with each index in
that name separated by a period (.), for example mystem.i.j. The function will insert the contents of each index
in the stem into the corresponding index of the std::list pointed to by a_plStem. |
||||
|
● |
Parameters |
||||
|
|
|
||||
|
● |
Returns |
||||
|
|
|
||||
|
● |
Messages None |
||||
|
● |
Usage The
following snippet of code illustrates how to use the GetRexxStem() function. // Access the manager.m_pManager = Manager();// Access my stage.m_pStage = m_pManager->GetStage( *this );
... CString szName = “MYSTEM”; std::list< CString >
lStem; // If the stem is
defined; load the std::list lStem with the contents. If( m_pManager->GetRexxStem(
( LPCTSTR )szName, &lStem ) ) { ... } else { // Otherwise; do something
else. ... } ... |
|
bool
CStageManage::GetRexxArray( _in const char
*a_pszName, _out std::list<
CString > *a_plArray ); |
|
● |
Purpose Use GetRexxArray() to obtain the contents of the ooRexx
array, specified by; a_pszName. You must specify the name of the array, with each index
in that name enclosed in brackets([]), for example myarray[i][j]. The function will insert the contents of each
index in the array into the corresponding index of the std::list pointed to
by a_plArray. |
||||
|
● |
Parameters |
||||
|
|
|
||||
|
● |
Returns |
||||
|
|
|
||||
|
● |
Messages None |
||||
|
● |
Usage The
following snippet of code illustrates how to use the GetRexxArray() function. // Access the manager.m_pManager = Manager();// Access my stage.m_pStage = m_pManager->GetStage( *this );
... CString szName = “MYARRAY”; std::list< CString >
lArray; // If the array is
defined; load the std::list lArray with the contents. If(
m_pManager->GetRexxArray( ( LPCTSTR )szName, &lArray ) ) { ... } else { // Otherwise; do something
else. ... } ... |
|
DWORD
CStageManager::GetRexxStemEntry( _in const char *a_pszName, _in DWORD
a_dwIndex, _inout CString
*a_pszValue ); |
|
● |
Purpose Use GetRexxStemEntry() to access the contents of a stem
index, specified by the DWORD a_dwIndex. You must specify the name of the stem, with each index in
that name separated by a period (.), for example mystem.i.j. The function will insert the contents of the
specified index into the CString pointed to by a_pszValue. |
||||||
|
● |
Parameters |
||||||
|
|
|
||||||
|
● |
Returns |
||||||
|
|
|
||||||
|
● |
Messages None |
||||||
|
● |
Usage The
following snippet of code illustrates how to use the GetRexxStemEntry()
function. // Access the manager.m_pManager = Manager();// Access my stage.m_pStage = m_pManager->GetStage( *this );
... CString szStemName = “MYSTEM”; DWORD dwIndex = 10; CString szValue; // Access element
number 10. dwRetCode =
m_pManager->GetRexxStemEntry( ( LPCTSTR )szStemName, dwIndex,
&m_szValue ); if(
dwRetCode == _RC_REXX_SUCCESS_ ) { // OK - we have found the rexx stem index
entry. So, do something with it.. ... } else { // Otherwise; do something
else. ... } ... |
DWORD CStageManager::GetRexxArrayEntry( _in const char *a_pszName, _in DWORD a_dwIndex, _out CString *a_pszValue ); |
|
● |
Purpose Use GetRexxArrayEntry() to access the contents of an
array index, specified by the DWORD a_dwIndex. You must specify the name of the array, with each index
in that name enclosed in brackets([]), for example myarray[i][j]. The function will insert the contents of the
specified index into the CString pointed to by a_pszValue. |
||||||
|
● |
Parameters |
||||||
|
|
|
||||||
|
● |
Returns |
||||||
|
|
|
||||||
|
● |
Messages None |
||||||
|
● |
Usage The
following snippet of code illustrates how to use the GetRexxArrayEntry()
function. // Access the manager.m_pManager = Manager();// Access my stage.m_pStage = m_pManager->GetStage( *this );
... CString szArrayName =
“MYARRAY”; DWORD dwIndex = 10; CString szValue; // Access element
number 10. dwRetCode =
m_pManager->GetRexxArrayEntry( ( LPCTSTR )szArrayName, dwIndex,
&m_szValue ); if(
dwRetCode == _RC_REXX_SUCCESS_ ) { // OK - we have found the rexx array
index entry. So, do something with it.. ... } else { // Otherwise; do something
else. ... } ... |
|
DWORD
CStageManager::GetRexxStemSize( _in const char
*a_pszName ); |
|
● |
Purpose Use GetRexxStemSize() to determine the number of entries
in the stem specified by the constant character pointer a_pszName . |
||
|
● |
Parameters |
||
|
|
|
||
|
● |
Returns |
||
|
|
|
||
|
● |
Messages None |
||
|
● |
Usage The following example shows a how you might use
GetRexxStemSize() to determine the number of entries in a stem name specified
on your stage command argument. bool CMyStage::Initialise( void ) { // Access the manager. m_pManager = Manager(); // Access my stage. m_pStage = m_pManager->GetStage( *this ); ...
CString szName; // Access my argument. const char *pszArgument = m_pStage->Argument();
m_pToken->m_pszSource =
&pszArgument; m_pToken->m_pszTarget = &szName; // Extract the array name. m_pManager->ParseForToken( m_pToken );
// Store the size of the stem for use
later in our Go() function. m_dwArraySize =
m_pManager->GetRexxStemSize( ( LPCTSTR )szName ); ... return( true ) } |
DWORD CStageManager::GetRexxArraySize( _in const char *a_pszName ); |
|
● |
Purpose Use GetRexxArraySize() to determine the number of entries
in the array specified by the constant character pointer a_pszName . |
||
|
● |
Parameters |
||
|
|
|
||
|
● |
Returns |
||
|
|
|
||
|
● |
Messages None |
||
|
● |
Usage The following example shows a how you might use
GetRexxArraySize() to determine the number of entries in an array name
specified on your stage command argument. bool CMyStage::Initialise( void ) { // Access the manager. m_pManager = Manager(); // Access my stage. m_pStage = m_pManager->GetStage( *this ); ...
CString szName; // Access my argument. const char *pszArgument = m_pStage->Argument();
m_pToken->m_pszSource =
&pszArgument;
m_pToken->m_pszTarget = &szName; // Extract the array name. m_pManager->ParseForToken( m_pToken );
// Store the size of the array for use
later in our Go() function. m_dwArraySize =
m_pManager->GetRexxArraySize( ( LPCTSTR )szName ); ... return( true ) } |
|
bool
CStageManager::IsRexxVariable( _in const char
*a_pszName, _in DWORD a_dwType
); |
|
● |
Purpose Use IsRexxVariable() to determine if the specified name
defined by the constant character pointer a_pszName
is a currently defined ooRexx variable. |
||
|
● |
Parameters |
||
|
|
|
||
|
● |
Returns |
||
|
|
|
||
|
● |
Messages None |
||
|
● |
Usage The
following example shows a simple example of how to use the IsRexxVariable()
function to determine if the contents of the CString m_szName is a currently defined ooRexx variable. bool CMyStage::Initialise( void ) { // Access the manager. m_pManager = Manager(); // Access my stage. m_pStage = m_pManager->GetStage( *this ); ...
// If it's a variable ... if( m_pManager->IsRexxVariable( (
LPCTSTR )m_szName ) ) { ... return( false ); } ...return( true ); } |
|
bool
CStageManager::IsRexxStem( _in const char *a_pszName ); |
|
● |
Purpose Use IsRexxStem() to determine if the specified name
defined by the constant character pointer a_pszName
is a currently defined ooRexx stem. |
||
|
● |
Parameters |
||
|
|
|
||
|
● |
Returns |
||
|
|
|
||
|
● |
Messages None |
||
|
● |
Usage The following example shows a simple example of how to
use the IsRexxStem() function to determine if the contents of the CString m_szName is a currently defined ooRexx
stem. bool CMyStage::Initialise( void ) { // Access the manager. m_pManager = Manager(); // Access my stage. m_pStage = m_pManager->GetStage( *this ); ...
// If it's a stem ... if( m_pManager->IsRexxStem( ( LPCTSTR
)m_szName ) ) { ... return( false ); } ...return( true ); } |
|
bool
CStageManager::IsRexxArray( _in const char *a_pszName
); |
|
● |
Purpose Use IsRexxArray() to determine if the specified name
defined by the constant character pointer a_pszName
is a currently defined ooRexx array. |
||
|
● |
Parameters |
||
|
|
|
||
|
● |
Returns |
||
|
|
|
||
|
● |
Messages None |
||
|
● |
Usage The following example shows a simple example of how to
use the IsRexxArray() function to determine if the contents of the CString m_szName is a currently defined ooRexx
array. bool CMyStage::Initialise( void ) { // Access the manager. m_pManager = Manager(); // Access my stage. m_pStage = m_pManager->GetStage( *this ); ...
// If it's an array ... if( m_pManager->IsRexxArray( ( LPCTSTR
)m_szName ) ) { ... return( false ); } ...return( true ); } |
CRexxEntry *CStageManager::AddRexxEntry( void ); |
|
● |
Purpose Use AddRexxEntry() to add a Rexx variable, stem or array
update to the set of entries currently defined in the session Directory
Object. ooRexx will only allow the update of a variable, stem or
array within its own execution thread. Your Pipelines Stage DLL will execute
in a separate thread, and so, anything that you create, modify or destroy
will only get finalised after Pipelines has terminated. The AddRexxEntry()
function will create a new CRexxEntry object, adding it to a list of updates
to be actioned and return a pointer to it; so that you can fill in the
detail. This ‘TODO’ list will get processed by Pipelines automatically at the
close of play, so, any updates that you have added will be processed just
before Pipelines returns to its caller – ooRexx. |
||
|
● |
Parameters |
||
|
|
|
||
|
● |
Returns |
||
|
|
|
||
|
● |
Messages None |
||
|
● |
Usage The following example shows the
SRexxVariable structure and an edited excerpt from the CVar stage class
commands’ Go() function. The portion of code shown; illustrates how the
AddRexxEntry() function is used to create a new ooRexx variable. enum m_eRexxVariableAction { m_eUndefined, m_eUpdate, m_eDrop,
m_eAppend }; enum m_eRexxVariableType {
m_eVariable, m_eStem, m_eArray }; struct
SRexxVariable { std::list< CString > m_lStem; CString m_szName; CString m_szValue; DWORD m_dwAction; }; DWORD
CVar::Go( void ) { ... CString szRecord; // Create the new rexx entry
object. CRexxEntry *pRexxEntry =
m_pManager->AddRexxEntry(); pRexxEntry->Type(
CRexxEntry::m_eVariable ); // Set the initial action for update. pRexxEntry->Action(
CRexxEntry::m_eUpdate ); pRexxEntry->Name( m_szName ); pRexxEntry->Value( “” ); // Ok, now lets read and
process the primary input stream. for( ;; ) { // Read a record from the
primary input stream. if( !m_pManager->PeekRecord( *this, 0, &szRecord ) ) break; ... // Store the variable
value in the rexx entry structure. pRexxEntry->Value( szRecord ); // Write the record to
primary output stream. if( !m_pManager->WriteRecord(
*this, 0, &szRecord ) ) break; // Release the stage that
we read from. m_pManager->ConsumeRecord(
*this, 0 ); } ... return( _RC_SUCCESS_ ); } |
|
|