00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012
00013 #if defined(__GNUG__) && !defined(__APPLE__)
00014 #pragma implementation "rpn_handler.h"
00015 #endif
00016
00017
00018 #ifdef __BORLANDC__
00019 #pragma hdrstop
00020 #endif
00021
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <stdio.h>
00025
00026 #include "rpn_handler.h"
00027 #include "virtual_board_channel.h"
00028
00029 RpnHandler::RpnHandler( VirtualBoardChannel* parent, const char *expression_def)
00030 {
00031 this->m_parent= parent;
00032 this->m_rpn_items_array= NULL;
00033 this->m_tmp_rpn_items_array= NULL;
00034 this->m_rpn_array_alloc_size= 0;
00035 this->m_rpn_array_real_size= 0;
00036 this->m_expression_def= NULL;
00037 this->m_ref_channel_index= -1;
00038 this->Parse( expression_def);
00039 }
00040
00041 RpnHandler::~RpnHandler(void)
00042 {
00043 if( this->m_rpn_items_array!= NULL)
00044 delete[] this->m_rpn_items_array;
00045 if( this->m_tmp_rpn_items_array)
00046 delete[] this->m_tmp_rpn_items_array;
00047 if( this->m_expression_def)
00048 delete this->m_expression_def;
00049
00050 }
00051
00052 bool RpnHandler::Parse( const char *expression_def)
00053 {
00054
00055
00056
00057
00058 const int BLOCK_ALLOC_SIZE= 10;
00059 char* token;
00060 char* tmp_buff;
00061 this->m_ref_channel_index= -1;
00062 if( this->m_expression_def)
00063 delete this->m_expression_def;
00064 this->m_expression_def= new char[ strlen( expression_def)+ 1];
00065 tmp_buff= new char[ strlen( expression_def)+ 1];
00066 strcpy( this->m_expression_def, expression_def);
00067 strcpy( tmp_buff, expression_def);
00068
00069 if( this->m_rpn_items_array!= NULL)
00070 delete[] this->m_rpn_items_array;
00071
00072 this->m_rpn_array_alloc_size= BLOCK_ALLOC_SIZE;
00073 this->m_rpn_items_array= new RpnItem[ this->m_rpn_array_alloc_size];
00074 this->m_rpn_array_real_size= 0;
00075
00076 token= strtok( tmp_buff, ",");
00077 while( token!= NULL)
00078 {
00079 if( this->m_rpn_array_real_size> this->m_rpn_array_alloc_size)
00080 {
00081
00082 RpnItem *tmp= new RpnItem[ this->m_rpn_array_alloc_size+ BLOCK_ALLOC_SIZE];
00083 memcpy( tmp, this->m_rpn_items_array, sizeof( this->m_rpn_items_array[0])* this->m_rpn_array_alloc_size);
00084 delete[] this->m_rpn_items_array;
00085 this->m_rpn_items_array= tmp;
00086 this->m_rpn_array_alloc_size+= BLOCK_ALLOC_SIZE;
00087 }
00088
00089 this->m_rpn_items_array[ this->m_rpn_array_real_size].m_processed= false;
00090 this->m_rpn_items_array[ this->m_rpn_array_real_size].m_type= (RpnTypes)-1;
00091
00092 for( int i= 0; i< RPN_OPERAND_CONST; i++)
00093 {
00094 if( !stricmp( token, RpnTypesNames[ i]))
00095 {
00096
00097
00098 this->m_rpn_items_array[ this->m_rpn_array_real_size].m_type= (RpnTypes)i;
00099 this->m_rpn_items_array[ this->m_rpn_array_real_size].m_value= 0;
00100
00101 if( this->m_ref_channel_index== -1)
00102 {
00103 switch( i)
00104 {
00105 case RPN_OPERAND_CH0:
00106 case RPN_OPERAND_CH1:
00107 case RPN_OPERAND_CH2:
00108 case RPN_OPERAND_CH3:
00109 case RPN_OPERAND_CH4:
00110 case RPN_OPERAND_CH5:
00111 case RPN_OPERAND_CH6:
00112 case RPN_OPERAND_CH7:
00113 this->m_ref_channel_index= i- RPN_OPERAND_CH0;
00114 break;
00115 }
00116 }
00117
00118 break;
00119 }
00120 }
00121
00122 if( this->m_rpn_items_array[ this->m_rpn_array_real_size].m_type== (RpnTypes)-1)
00123 {
00124
00125 this->m_rpn_items_array[ this->m_rpn_array_real_size].m_type= RPN_OPERAND_CONST;
00126 this->m_rpn_items_array[ this->m_rpn_array_real_size].m_value= atof( token);
00127 }
00128 this->m_rpn_array_real_size++;
00129
00130 token= strtok( NULL, ",");
00131 }
00132 delete tmp_buff;
00133 if( this->m_tmp_rpn_items_array)
00134 delete[] this->m_tmp_rpn_items_array;
00135 this->m_tmp_rpn_items_array= new RpnItem[ this->m_rpn_array_alloc_size];
00136
00137 return true;
00138 }
00139 const char* RpnHandler::Format( )
00140 {
00141 return this->m_expression_def? this->m_expression_def: "";
00142 }
00143 bool RpnHandler::Test( void)
00144 {
00145
00146
00147
00148 return this->DoEval( NULL);
00149 }
00150 bool RpnHandler::Eval( double &result)
00151 {
00152 return this->DoEval( &result);
00153 }
00154 bool RpnHandler::DoEval( double *p_result)
00155 {
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 if( p_result)
00167 *p_result= 0;
00168
00169
00170 memcpy( this->m_tmp_rpn_items_array, this->m_rpn_items_array, this->m_rpn_array_real_size* sizeof( this->m_rpn_items_array[ 0]));
00171
00172 int current_index= 0;
00173 int num_unprocessed= this->m_rpn_array_real_size;
00174
00175
00176 for( current_index= 0; current_index< this->m_rpn_array_real_size; current_index++)
00177 {
00178 if( this->m_tmp_rpn_items_array[ current_index].m_processed)
00179 continue;
00180
00181 switch( this->m_tmp_rpn_items_array[ current_index].m_type)
00182 {
00183 case RPN_OPERATOR_ADD:
00184 case RPN_OPERATOR_SUB:
00185 case RPN_OPERATOR_MUL:
00186 case RPN_OPERATOR_DIV:
00187 break;
00188 case RPN_OPERAND_CH0:
00189 case RPN_OPERAND_CH1:
00190 case RPN_OPERAND_CH2:
00191 case RPN_OPERAND_CH3:
00192 case RPN_OPERAND_CH4:
00193 case RPN_OPERAND_CH5:
00194 case RPN_OPERAND_CH6:
00195 case RPN_OPERAND_CH7:
00196 continue;
00197 case RPN_OPERAND_CONST:
00198 continue;
00199 default:
00200
00201 return false;
00202 }
00203
00204
00205 double operands[ 2]= { 0, 0};
00206 int back_index= current_index- 1;
00207 for( int operand= 0; operand< 2; operand++)
00208 {
00209 bool search= true;
00210 for( ; ( back_index>= 0)&& search; back_index--)
00211 {
00212 if( this->m_tmp_rpn_items_array[ back_index].m_processed)
00213 continue;
00214 switch( this->m_tmp_rpn_items_array[ back_index].m_type)
00215 {
00216 case RPN_OPERAND_CH0:
00217 case RPN_OPERAND_CH1:
00218 case RPN_OPERAND_CH2:
00219 case RPN_OPERAND_CH3:
00220 case RPN_OPERAND_CH4:
00221 case RPN_OPERAND_CH5:
00222 case RPN_OPERAND_CH6:
00223 case RPN_OPERAND_CH7:
00224 if( p_result)
00225 {
00226 if( !this->m_parent->GetChannelValueVolt( this->m_tmp_rpn_items_array[ back_index].m_type- RPN_OPERAND_CH0, operands[ operand]))
00227 return false;
00228 operands[ operand]*= 1000;
00229 }
00230 this->m_tmp_rpn_items_array[ back_index].m_processed= true;
00231 search= false;
00232 num_unprocessed--;
00233 break;
00234 case RPN_OPERAND_CONST:
00235 if( p_result)
00236 {
00237 operands[ operand]= this->m_tmp_rpn_items_array[ back_index].m_value;
00238 }
00239 this->m_tmp_rpn_items_array[ back_index].m_processed= true;
00240 search= false;
00241 num_unprocessed--;
00242 break;
00243 default:
00244
00245 return false;
00246 }
00247 }
00248 if( search)
00249 {
00250
00251 return false;
00252 }
00253 }
00254
00255
00256 switch( this->m_tmp_rpn_items_array[ current_index].m_type)
00257 {
00258 case RPN_OPERATOR_ADD:
00259 if( p_result)
00260 {
00261 this->m_tmp_rpn_items_array[ current_index].m_value= operands[ 1]+ operands[ 0];
00262 }
00263 break;
00264 case RPN_OPERATOR_SUB:
00265 if( p_result)
00266 {
00267 this->m_tmp_rpn_items_array[ current_index].m_value= operands[ 1]- operands[ 0];
00268 }
00269 break;
00270 case RPN_OPERATOR_MUL:
00271 if( p_result)
00272 {
00273 this->m_tmp_rpn_items_array[ current_index].m_value= operands[ 1]* operands[ 0];
00274 }
00275 break;
00276 case RPN_OPERATOR_DIV:
00277 if( p_result)
00278 {
00279 if( operands[ 0]== 0)
00280 return false;
00281 this->m_tmp_rpn_items_array[ current_index].m_value= operands[ 1]/ operands[ 0];
00282 }
00283 break;
00284 default:
00285
00286 return false;
00287 }
00288 this->m_tmp_rpn_items_array[ current_index].m_type= RPN_OPERAND_CONST;
00289 }
00290
00291
00292 if( num_unprocessed!= 1)
00293 return false;
00294
00295
00296 for( int back_index= this->m_rpn_array_real_size- 1; back_index>= 0; back_index--)
00297 {
00298 if( this->m_tmp_rpn_items_array[ back_index].m_processed)
00299 continue;
00300
00301 switch( this->m_tmp_rpn_items_array[ back_index].m_type)
00302 {
00303 case RPN_OPERAND_CH0:
00304 case RPN_OPERAND_CH1:
00305 case RPN_OPERAND_CH2:
00306 case RPN_OPERAND_CH3:
00307 case RPN_OPERAND_CH4:
00308 case RPN_OPERAND_CH5:
00309 case RPN_OPERAND_CH6:
00310 case RPN_OPERAND_CH7:
00311 if( p_result)
00312 {
00313 if( !this->m_parent->GetChannelValueVolt( this->m_tmp_rpn_items_array[ back_index].m_type- RPN_OPERAND_CH0, *p_result))
00314 return false;
00315 }
00316 return true;
00317 case RPN_OPERAND_CONST:
00318 if( p_result)
00319 {
00320 *p_result= this->m_tmp_rpn_items_array[ back_index].m_value* 0.001;
00321 }
00322 return true;
00323 default:
00324
00325 return false;
00326 }
00327 }
00328 return true;
00329 }
00330
00331 unsigned int RpnHandler::GetBufferCount( void)
00332 {
00333 if( this->m_ref_channel_index< 0)
00334 return (unsigned int)-1;
00335 unsigned int value= 0;
00336 if( !this->m_parent->GetChannelBufferCount( this->m_ref_channel_index, value))
00337 return (unsigned int)-1;
00338 return value;
00339 }
00340