Main Page Class Hierarchy Compound List File List Compound Members File Members

# result_template.cpp

Go to the documentation of this file.

    00001 /*
    00002  * result_template.cpp -- Template of a result message class for use
    00003  *                        in the mutable server model.
    00004  *
    00005  * See request_template.cpp for example code and comments
    00006  * or magserverresult.cpp for a detailed implementation example.
    00007  */
    00008
    00009 // START WITH THE CLASS DECLARATION IN THE .h FILE.
    00010
    00011 //******************************************************************************
    00012 // STEP 1: Do a global replacement of the string "ResultTemplate"
    00013 //         with the name of the new class
    00014 //******************************************************************************
    00015
    00016
    00017 //******************************************************************************
    00018 // STEP 2: Replace the name of the include file for the class declaration
    00019 //
    00020 //******************************************************************************
    00021 #include "result_template.h"
    00022
    00023
    00024
    00025 //******************************************************************************
    00026 // STEP 3: Update the constructor to initialize all variables that were
    00027 //         declared in the .h (Base classes will initialize their own
    00028 //         variables as needed).
    00029 //
    00030 //******************************************************************************
    00031 //------------------------------------------------------------------------------
    00032 ResultTemplate::ResultTemplate()
    00033 {
    00034    // INITIALIZE ANY CLASS VARIABLES
    00035
    00036    // Any pointers that will reference memory allocated by this class
    00037    // MUST be NULLified here.
    00038
    00039 }
    00040
    00041 //******************************************************************************
    00042 // STEP 4: If the destructor declaration was included in the .h file,
    00043 //         uncomment and implement it here, otherwise remove this method.
    00044 //
    00045 //******************************************************************************
    00046 //------------------------------------------------------------------------------
    00047 /*
    00048 ResultTemplate::~ResultTemplate()
    00049 {
    00050    // MEMORY ALLOCATED WITHIN THIS CLASS MUST BE DELETED HERE
    00051    // (IF NOT PREVIOUSLY)
    00052
    00053    // EXAMPLE
    00054    // if ( MyCharPointer != NULL )
    00055    // {
    00056    //   delete [] MyCharPointer;
    00057    // }
    00058    // The class can't be used after destruction, so there is no need
    00059    // to set MyCharPointer back to NULL.
    00060 }
    00061 */
    00062
    00063 //******************************************************************************
    00064 // STEP 5: Implement the accessor methods declared for this specific class:
    00065 //         (these examples equate to those in the template .h file)
    00066 //
    00067 //******************************************************************************
    00068
    00069 //------------------------------------------------------------------------------
    00070 /*
    00071 void ResultTemplate::SetMyInt( int parameterA )
    00072 {
    00073    MyInt = parameterA;
    00074 }
    00075 */
    00076 //------------------------------------------------------------------------------
    00077 /*
    00078 int ResultTemplate::GetMyInt() { return MyInt; }
    00079 */
    00080
    00081
    00082 //******************************************************************************
    00083 // STEP 6: Implement the virtual methods that were declared but not defined
    00084 //         in the Base classes from which this one is derived.
    00085 //         (Deriving from MutableServerResult means there are three, there may
    00086 //         be a different number for a different base class).
    00087 //
    00088 //******************************************************************************
    00089
    00090
    00091 //------------------------------------------------------------------------------
    00092 long ResultTemplate::BufferInitAlloc()
    00093 {
    00094    long ExpectedBufferLength = 0;
    00095
    00096    // First, call the immediate base class's method to get the buffer length
    00097    // required by all base classes.
    00098    //
    00099    // THIS CALL MUST BE INCLUDED IN THIS METHOD,
    00100    // AND IT MUST BE CALLED FOR THE CLASS FROM WHICH THIS ONE IS DERIVED.
    00101    //
    00102    ExpectedBufferLength = MutableServerResult::BufferInitAlloc();
    00103
    00104    // ADD THE ADDITIONAL BUFFER LENGTH NEEDED BY THIS CLASS'S VARIABLES
    00105    //
    00106    // Assuming a single int value which will never be more than 15 digits,
    00107    // it might be as simple as the line below.  For more complex results
    00108    // (for example magnitude results that might have n channels included),
    00109    // it could be much more complex.
    00110
    00111    ExpectedBufferLength += 15;
    00112
    00113    return ExpectedBufferLength;
    00114 }
    00115 //------------------------------------------------------------------------------
    00116 //------------------------------------------------------------------------------
    00117 void ResultTemplate::FormatDerivativeData()
    00118 {
    00119    // First, prepare the leading part of the buffer....that is, prepare
    00120    // the buffer part used by the base class(es):
    00121    //
    00122    // THIS CALL MUST BE PERFORMED AT THE START OF THIS METHOD,
    00123    // AND IT MUST BE CALLED FOR THE CLASS FROM WHICH THIS ONE IS DERIVED.
    00124    //
    00125    MutableServerResult::FormatDerivativeData();
    00126
    00127
    00128    // NOW FORMAT AND APPEND THE BUFFER CONTENTS FOR THIS CLASS.
    00129
    00130    // THE ACTUAL BUFFER IS IMPLEMENTED WITH A C++ basic_string TYPE.
    00131    // A CHAR VALUE MAY BE APPENDED TO THE BUFFER WITH +=
    00132    //
    00133    // MessageBuffer += "SOME STRING VALUE";
    00134
    00135
    00136    // GENERALLY, THIS CLASS HEIRARCHY BREAKS MESSAGES INTO MULTIPLE LINES
    00137    // WITH '\n'.  THE END OF THE MESSAGE IS MARKED WITH AN ADDITIONAL '\n'.
    00138
    00139
    00140    /*
    00141    // Say that this class has some result value of type int, the code to
    00142    // include that value in the message buffer might look something like:
    00143
    00144    char _myint[18];
    00145
    00146    sprintf( _myint, "%d\n MyInt );
    00147
    00148    MessageBuffer += _myint;
    00149    */
    00150 }
    00151 //------------------------------------------------------------------------------
    00152 //------------------------------------------------------------------------------
    00153 void ResultTemplate::ParseDerivativeData()
    00154 {
    00155    // One of the first things done as part of the parse process is that the
    00156    // message is put into the (base class's) variable MessageBuffer
    00157    //
    00158    // Lines are then snipped off the front of the buffer as they are processed.
    00159    //
    00160
    00161    // First, parse the leading part of the buffer....that is,
    00162    // the buffer part used by the base class(es):
    00163    //
    00164    // THIS CALL MUST BE PERFORMED AT THE START OF THIS METHOD,
    00165    // AND IT MUST BE CALLED FOR THE CLASS FROM WHICH THIS ONE IS DERIVED.
    00166    //
    00167    MutableServerResult::ParseDerivativeData();
    00168
    00169
    00170    long _index;            // end of line index
    00171    std::string _readline;  // work buffer
    00172
    00173
    00174    // NOW PARSE THE PORTION OF THE BUFFER RELEVANT TO THIS MESSAGE CLASS
    00175
    00176    // NOTE THAT ALL ERRORS ARE REPORTED BY THROWING A worm_exception OBJECT.
    00177    // THERE ARE TWO WAYS TO FORMAT THE ERROR MESSAGE CONTAINED THEREIN, EITHER
    00178    // WITH A SIMPLE STRING:
    00179    //
    00180    //    throw worm_exception("My error message");
    00181    //
    00182    // OR BUILT UP FROM STRINGS AND VARAIBLES
    00183    //
    00184    //    worm_exception my_exception("ResultTemplate::ParseDerivativeData() Error: ");
    00185    //                   my_exception += SomeStringVariable;
    00186    //                   my_exception += " ";
    00187    //                   my_exception += SomeOtherStringVariable;
    00188    //    throw my_exception;
    00189    //
    00190    // FYI, THE worm_exception IS CAUGHT AND REPORTED BY THE SERVER
    00191
    00192
    00193    // MESSAGE LINES ARE GENERALLY HANDLED WITH ONE OR MORE REPETITIONS OF
    00194    // THE FOLLOWING FOUR STEPS.
    00195    // THE MESSAGE IS TERMINATED WITH AN EMPTY LINE ('\n' ALONE),
    00196    // THUS, EITHER HAVE A FIXED NUMBER OF LINES FOR THE CLASS, OR BE
    00197    // PREPARED FOR MESSAGE TERMINATION.
    00198
    00199
    00200    // 1. Find the end of the next line in the buffer
    00201    //
    00202    if ( (_index = MessageBuffer.find("\n")) == MessageBuffer.npos )
    00203    {
    00204       // First way to throw a worm_exception object
    00205       throw worm_exception("Unterminated message while parsing ResultTemplate line");
    00206    }
    00207
    00208    // 2. Extract the line from the buffer
    00209    //
    00210    _readline = MessageBuffer.substr( 0 , _index );
    00211
    00212    // 3. Remove the line from the buffer
    00213    //
    00214    MessageBuffer.erase( 0 , _index + 1 );
    00215
    00216    // 4. Parse the message line
    00217
    00218    if ( sscanf( _readline.c_str()
    00219               , "%d %d %s"
    00220               , &MyIntVariable
    00221               , &MySecondIntVariable
    00222               ,  MyCharVariable
    00223               ) != 3
    00224       )
    00225    {
    00226       worm_exception my_exception("ResultTemplate::ParseDerivativeData() Error: Invalid line\n" );
    00227                      my_exception += _readline.c_str();
    00228       throw my_exception;
    00229    }
    00230
    00231    // NOTE THAT THE ABOVE 'MyXXXVariables' ARE EXPECTED TO BE CLASS VARIABLES,
    00232    // THUS AFTER PARSING, THIS CLASS BECOMES A DATA CONTAINER ALONG WITH
    00233    // MESSAGE FORMATTER/PARSER
    00234
    00235 }
    00236
    00237 //------------------------------------------------------------------------------
    00238