00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "fennel/common/CommonPreamble.h"
00026 #include "fennel/tuple/TupleDescriptor.h"
00027 #include "fennel/tuple/TupleData.h"
00028 #include "fennel/tuple/TupleAccessor.h"
00029 #include "fennel/tuple/TuplePrinter.h"
00030 #include "fennel/tuple/AttributeAccessor.h"
00031 #include "fennel/tuple/StandardTypeDescriptor.h"
00032 #include "fennel/common/TraceSource.h"
00033 #include "fennel/calculator/BoolInstruction.h"
00034 #include "fennel/calculator/BoolNativeInstruction.h"
00035 #include "fennel/calculator/Calculator.h"
00036 #include "fennel/calculator/IntegralNativeInstruction.h"
00037 #include "fennel/calculator/JumpInstruction.h"
00038 #include "fennel/calculator/NativeInstruction.h"
00039 #include "fennel/calculator/NativeNativeInstruction.h"
00040 #include "fennel/calculator/ReturnInstruction.h"
00041 #include "fennel/calculator/ExtendedInstruction.h"
00042 #include "fennel/calculator/InstructionCommon.h"
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045 #include <string>
00046 #include <boost/scoped_array.hpp>
00047 #include <boost/test/unit_test_suite.hpp>
00048 #include <limits>
00049 #include <iostream.h>
00050 #include <math.h>
00051 using namespace std;
00052 using namespace fennel;
00053 char *ProgramName;
00054 void
00055 fail(const char *str, int line) {
00056 assert(ProgramName);
00057 assert(str);
00058 printf("%s: unit test failed: |%s| line %d\n", ProgramName, str, line);
00059 exit(-1);
00060 }
00061
00062
00063
00064 void convertDoubleToFloat(
00065 RegisterRef<float>* regOut,
00066 RegisterRef<double>* regIn)
00067 {
00068 regOut->value((float)regIn->value());
00069 }
00070 void convertFloatToDouble(
00071 RegisterRef<double>* regOut,
00072 RegisterRef<float>* regIn)
00073 {
00074 regOut->value((double)regIn->value());
00075 }
00076 void convertFloatToInt(
00077 RegisterRef<int>* regOut,
00078 RegisterRef<float>* regIn)
00079 {
00080 regOut->value((int)regIn->value());
00081 }
00082 void convertIntToFloat(
00083 RegisterRef<float>* regOut,
00084 RegisterRef<int>* regIn)
00085 {
00086 regOut->value((float)regIn->value());
00087 }
00091 void convertDecimal(
00092 RegisterRef<int32_t>* resultReg,
00093 RegisterRef<int32_t>* inputReg,
00094 RegisterRef<int32_t>* exponentReg)
00095 {
00096 int32_t in = inputReg->value();
00097 int32_t exp = exponentReg->value();
00098 int32_t result = in;
00099 if (exp < 0) {
00100 while (exp++ < 0) {
00101 result /= 10;
00102 }
00103 } else {
00104 while (exp-- > 0) {
00105 result *= 10;
00106 }
00107 }
00108 resultReg->value(result);
00109 }
00110
00111 void convertStringToExactNumber(
00112 RegisterRef<int>* regOut,
00113 RegisterRef<char *>* regIn)
00114 {
00115 #if 0
00116
00117 uint srcL = regIn->getS();
00118
00119
00120 char *nullTermStr = new char[srcL + 1];
00121 nullTermStr[srcL + 1] = 0;
00122 memcpy(nullTermStr, regIn->pointer(), srcL);
00123 regOut->value(strtol(nullTermStr, 0, 10));
00124 delete [] nullTermStr;
00125 #endif
00126 #if 0
00127
00128
00129 const char *pString = regIn->valueToString().c_str();
00130 assert(pString);
00131 int iValue = atoi(pString);
00132 regOut->value(iValue);
00133 #endif
00134
00135
00136
00137 uint srcL = regIn->stringLength();
00138 char *nullTermStr = new char[srcL + 1];
00139 nullTermStr[srcL] = 0;
00140 memcpy(nullTermStr, regIn->pointer(), srcL);
00141 regOut->value(strtol(nullTermStr, 0, 10));
00142 delete [] nullTermStr;
00143 }
00144
00145 #if 0
00146
00147 void convertExactNumberToString(
00148 RegisterRef<char *>* regOut,
00149 RegisterRef<int>* regIn)
00150 {
00151 #if 1
00152
00153
00154 char *nullTermStr = new char[256];
00155 sprintf(nullTermStr, "%d", regIn->value());
00156
00157 uint dstL = regOut->storage();
00158 uint newL = strlen(nullTermStr);
00159
00160 printf("dstL = %d newL = %d\n", dstL, newL);
00161
00162 if (newL > dstL) {
00163
00164
00165
00166 assert(0);
00167
00168 memcpy(regOut->pointer(), nullTermStr, dstL);
00169 regOut->putS(dstL);
00170 throw CalcMessage("22001", 0);
00171 printf("ConvertExactNumberToString\n");
00172 assert(newL <= dstL);
00173 }
00174
00175 regOut->putS(newL);
00176 memcpy(regOut->pointer(), nullTermStr, newL);
00177 delete [] nullTermStr;
00178 #endif
00179 #if 0
00180
00181
00182 const char *pString = regIn->valueToString().c_str();
00183 assert(pString);
00184 regOut->value(const_cast<char*>(pString));
00185 #endif
00186 }
00187 #endif
00188
00189 void convertStringToFloat(
00190 RegisterRef<float>* regOut,
00191 RegisterRef<char *>* regIn)
00192 {
00193
00194 }
00195
00196 void convertFloatToString(
00197 RegisterRef<char *>* regOut,
00198 RegisterRef<float>* regIn)
00199 {
00200
00201 }
00202
00203 void convertStringToDouble(
00204 RegisterRef<double>* regOut,
00205 RegisterRef<char *>* regIn)
00206 {
00207
00208 }
00209
00210 void convertDoubleToString(
00211 RegisterRef<char *>* regOut,
00212 RegisterRef<double>* regIn)
00213 {}
00214
00215
00216
00217
00218
00225 class TestCalculator : public Calculator {
00226 TupleDescriptor _tupleDescLiteral;
00227 TupleDescriptor _tupleDescInput;
00228 TupleDescriptor _tupleDescOutput;
00229 TupleDescriptor _tupleDescLocal;
00230 TupleDescriptor _tupleDescStatus;
00231 bool _isNullable;
00232 ExtendedInstructionDef *_instrDef;
00233 TupleAccessor _tupleAccessorLiteral;
00234 TupleAccessor _tupleAccessorInput;
00235 TupleAccessor _tupleAccessorOutput;
00236 TupleAccessor _tupleAccessorLocal;
00237 TupleAccessor _tupleAccessorStatus;
00238 boost::scoped_array<FixedBuffer> _pTupleBufLiteral;
00239 boost::scoped_array<FixedBuffer> _pTupleBufInput;
00240 boost::scoped_array<FixedBuffer> _pTupleBufOutput;
00241 boost::scoped_array<FixedBuffer> _pTupleBufLocal;
00242 boost::scoped_array<FixedBuffer> _pTupleBufStatus;
00243 TupleData _tupleDataLiteral;
00244 TupleData _tupleDataInput;
00245 TupleData _tupleDataOutput;
00246 TupleData _tupleDataLocal;
00247 TupleData _tupleDataStatus;
00248 public:
00249 TestCalculator(
00250 DynamicParamManager *pdpm,
00251 bool isNullable,
00252 ExtendedInstructionDef *instrDef)
00253 : Calculator(pdpm, 0, 0, 0, 0, 0, 0),
00254 _isNullable(isNullable),
00255 _instrDef(instrDef),
00256 _pTupleBufLiteral(NULL),
00257 _pTupleBufInput(NULL),
00258 _pTupleBufOutput(NULL),
00259 _pTupleBufLocal(NULL),
00260 _pTupleBufStatus(NULL),
00261 _tupleDataLiteral(),
00262 _tupleDataInput(),
00263 _tupleDataOutput(),
00264 _tupleDataLocal(),
00265 _tupleDataStatus()
00266 {
00267 setUp();
00268 }
00269
00270 void setUp() {
00271 const vector<StandardTypeDescriptorOrdinal> parameterTypes =
00272 _instrDef->getParameterTypes();
00273
00274 StandardTypeDescriptorFactory typeFactory;
00275 for (uint i = 0; i < parameterTypes.size(); i++) {
00276 StoredTypeDescriptor const &typeDesc =
00277 typeFactory.newDataType(parameterTypes[i]);
00278 if (i == 0) {
00279
00280 _tupleDescOutput.push_back(
00281 TupleAttributeDescriptor(typeDesc, _isNullable));
00282 } else if (i > 0) {
00283
00284 _tupleDescInput.push_back(
00285 TupleAttributeDescriptor(typeDesc, _isNullable));
00286 }
00287 }
00288
00289
00290
00291
00292
00293
00294 _tupleAccessorLiteral.compute(
00295 _tupleDescLiteral, TUPLE_FORMAT_ALL_FIXED);
00296 _tupleAccessorInput.compute(_tupleDescInput, TUPLE_FORMAT_ALL_FIXED);
00297 _tupleAccessorOutput.compute(_tupleDescOutput, TUPLE_FORMAT_ALL_FIXED);
00298 _tupleAccessorLocal.compute(_tupleDescLocal, TUPLE_FORMAT_ALL_FIXED);
00299 _tupleAccessorStatus.compute(_tupleDescStatus, TUPLE_FORMAT_ALL_FIXED);
00300
00301 _pTupleBufLiteral.reset(
00302 new FixedBuffer[_tupleAccessorLiteral.getMaxByteCount()]);
00303 _pTupleBufInput.reset(
00304 new FixedBuffer[_tupleAccessorInput.getMaxByteCount()]);
00305 _pTupleBufOutput.reset(
00306 new FixedBuffer[_tupleAccessorOutput.getMaxByteCount()]);
00307 _pTupleBufLocal.reset(
00308 new FixedBuffer[_tupleAccessorLocal.getMaxByteCount()]);
00309 _pTupleBufStatus.reset(
00310 new FixedBuffer[_tupleAccessorStatus.getMaxByteCount()]);
00311
00312 _tupleAccessorLiteral.setCurrentTupleBuf(
00313 _pTupleBufLiteral.get(), false);
00314 _tupleAccessorInput.setCurrentTupleBuf(_pTupleBufInput.get(), false);
00315 _tupleAccessorOutput.setCurrentTupleBuf(_pTupleBufOutput.get(), false);
00316 _tupleAccessorLocal.setCurrentTupleBuf(_pTupleBufLocal.get(), false);
00317 _tupleAccessorStatus.setCurrentTupleBuf(_pTupleBufStatus.get(), false);
00318
00319
00320 _tupleDataLiteral.compute(_tupleDescLiteral);
00321 _tupleDataInput.compute(_tupleDescInput);
00322 _tupleDataOutput.compute(_tupleDescOutput);
00323 _tupleDataLocal.compute(_tupleDescLocal);
00324 _tupleDataStatus.compute(_tupleDescStatus);
00325
00326
00327 _tupleAccessorLiteral.unmarshal(_tupleDataLiteral);
00328 _tupleAccessorInput.unmarshal(_tupleDataInput);
00329 _tupleAccessorOutput.unmarshal(_tupleDataOutput);
00330 _tupleAccessorLocal.unmarshal(_tupleDataLocal);
00331 }
00332
00333 template <typename T>
00334 void setInput(int index, T *valP)
00335 {
00336
00337
00338 _tupleDataInput[index].pData = reinterpret_cast<const uint8_t *>(valP);
00339 if (true) {
00340
00341 TuplePrinter tuplePrinter;
00342 printf("Literals\n");
00343 tuplePrinter.print(cout, _tupleDescLiteral, _tupleDataLiteral);
00344 printf("\nInput\n");
00345 tuplePrinter.print(cout, _tupleDescInput, _tupleDataInput);
00346 cout << endl;
00347 printf("\nOutput\n");
00348 tuplePrinter.print(cout, _tupleDescOutput, _tupleDataOutput);
00349 cout << endl;
00350 printf("\nLocal\n");
00351 tuplePrinter.print(cout, _tupleDescLocal, _tupleDataLocal);
00352 cout << endl;
00353 }
00354 }
00355 template <typename T>
00356 void setInput(int index, T *valP, TupleStorageByteLength length)
00357 {
00358
00359
00360 _tupleDataInput[index].pData = reinterpret_cast<const uint8_t *>(valP);
00361 _tupleDataInput[index].cbData = length;
00362 if (true) {
00363
00364 TuplePrinter tuplePrinter;
00365 printf("Literals\n");
00366 tuplePrinter.print(cout, _tupleDescLiteral, _tupleDataLiteral);
00367 printf("\nInput\n");
00368 tuplePrinter.print(cout, _tupleDescInput, _tupleDataInput);
00369 cout << endl;
00370 printf("\nOutput\n");
00371 tuplePrinter.print(cout, _tupleDescOutput, _tupleDataOutput);
00372 cout << endl;
00373 printf("\nLocal\n");
00374 tuplePrinter.print(cout, _tupleDescLocal, _tupleDataLocal);
00375 cout << endl;
00376 }
00377 }
00378
00379 template <typename T>
00380 void setOutput(
00381 int index,
00382 T *valP,
00383 TupleStorageByteLength cbData,
00384 TupleStorageByteLength cbStorage)
00385 {
00386
00387
00388 _tupleDataOutput[index].pData = reinterpret_cast<const uint8_t *>(valP);
00389 _tupleDataOutput[index].cbData = cbData;
00390 _tupleDescOutput[index].cbStorage = cbStorage;
00391 if (true) {
00392
00393 TuplePrinter tuplePrinter;
00394 printf("Literals\n");
00395 tuplePrinter.print(cout, _tupleDescLiteral, _tupleDataLiteral);
00396 printf("\nInput\n");
00397 tuplePrinter.print(cout, _tupleDescInput, _tupleDataInput);
00398 cout << endl;
00399 printf("\nOutput\n");
00400 tuplePrinter.print(cout, _tupleDescOutput, _tupleDataOutput);
00401 cout << endl;
00402 printf("\nLocal\n");
00403 tuplePrinter.print(cout, _tupleDescLocal, _tupleDataLocal);
00404 cout << endl;
00405 }
00406 }
00407 void printOutput() {
00408 TuplePrinter tuplePrinter;
00409 printf("\nOutput\n");
00410 tuplePrinter.print(cout, _tupleDescOutput, _tupleDataOutput);
00411 cout << endl;
00412 }
00413 void bind()
00414 {
00415 Calculator::bind(
00416 RegisterReference::ELiteral,
00417 &_tupleDataLiteral,
00418 _tupleDescLiteral);
00419 Calculator::bind(
00420 RegisterReference::EInput,
00421 &_tupleDataInput,
00422 _tupleDescInput);
00423 Calculator::bind(
00424 RegisterReference::EOutput,
00425 &_tupleDataOutput,
00426 _tupleDescOutput);
00427 Calculator::bind(
00428 RegisterReference::ELocal,
00429 &_tupleDataLocal,
00430 _tupleDescLocal);
00431 Calculator::bind(
00432 RegisterReference::EStatus,
00433 &_tupleDataStatus,
00434 _tupleDescStatus);
00435 }
00436
00437 template <typename T>
00438 void getOutput(
00439 int i,
00440 T &val)
00441 {
00442 val = *(reinterpret_cast<T *>(const_cast<PBuffer>(
00443 _tupleDataOutput[i].pData)));
00444 }
00445
00446 template <typename T>
00447 void getOutputP(
00448 int i,
00449 T &val)
00450 {
00451 val = (reinterpret_cast<T>(const_cast<PBuffer>(
00452 _tupleDataOutput[i].pData)));
00453 }
00454 };
00455
00456
00457
00458
00459 void printTestHeader(const char *msg)
00460 {
00461 printf("=========================================================\n");
00462 printf("=========================================================\n");
00463 printf("=====\n");
00464 printf("===== ");
00465 printf("%s", msg);
00466 printf("\n");
00467 printf("=====\n");
00468 printf("=========================================================\n");
00469 printf("=========================================================\n");
00470 }
00471
00472 void testConvertDoubleToFloat(double val, float expected)
00473 {
00474 printTestHeader("testConvertDoubleToFloat()");
00475 ExtendedInstructionTable table;
00476 vector<StandardTypeDescriptorOrdinal> parameterTypes;
00477
00478 parameterTypes.resize(2);
00479 parameterTypes[0] = STANDARD_TYPE_REAL;
00480 parameterTypes[1] = STANDARD_TYPE_DOUBLE;
00481 table.add(
00482 "convert",
00483 parameterTypes,
00484 (ExtendedInstruction2<float,double>*) NULL,
00485 &convertDoubleToFloat);
00486
00487 ExtendedInstructionDef *pDef = table["convert(r,d)"];
00488 assert(pDef != NULL);
00489 assert(pDef->getName() == string("convert"));
00490 assert(pDef->getParameterTypes().size() == 2);
00491
00492 ExtendedInstructionDef *pNonExistentDef = table["convert(d,r)"];
00493 assert(pNonExistentDef == NULL);
00494
00495 DynamicParamManager dpm;
00496 TestCalculator c(&dpm, true, pDef);
00497 c.setInput(0, &val);
00498
00499 vector<RegisterReference *> regRefs(2);
00500 regRefs[0] = new RegisterRef<float>(
00501 RegisterReference::EOutput, 0,
00502 STANDARD_TYPE_REAL);
00503 regRefs[1] = new RegisterRef<double>(
00504 RegisterReference::EInput, 0,
00505 STANDARD_TYPE_DOUBLE);
00506 c.appendRegRef(regRefs[0]);
00507 c.appendRegRef(regRefs[1]);
00508 c.bind();
00509
00510
00511 ExtendedInstruction *pInstr = pDef->createInstruction(regRefs);
00512 assert(pInstr != NULL);
00513
00514 c.appendInstruction(pInstr);
00515 c.exec();
00516 c.printOutput();
00517 float f;
00518 c.getOutput(0, f);
00519 cout << f << endl;
00520 assert(fabs(expected - f) < 0.0001);
00521 };
00522
00523 void testConvertFloatToDouble(float val, double expected)
00524 {
00525 printTestHeader("testConvertFloatToDouble()");
00526 ExtendedInstructionTable table;
00527 vector<StandardTypeDescriptorOrdinal> parameterTypes;
00528
00529 parameterTypes.resize(2);
00530 parameterTypes[0] = STANDARD_TYPE_DOUBLE;
00531 parameterTypes[1] = STANDARD_TYPE_REAL;
00532 table.add(
00533 "convert",
00534 parameterTypes,
00535 (ExtendedInstruction2<double, float>*) NULL,
00536 &convertFloatToDouble);
00537
00538 ExtendedInstructionDef *pDef = table["convert(d,r)"];
00539 assert(pDef != NULL);
00540 assert(pDef->getName() == string("convert"));
00541 assert(pDef->getParameterTypes().size() == 2);
00542
00543 DynamicParamManager dpm;
00544 TestCalculator c(&dpm, true, pDef);
00545 c.setInput(0, &val);
00546
00547 vector<RegisterReference *> regRefs(2);
00548 regRefs[0] = new RegisterRef<double>(
00549 RegisterReference::EOutput, 0,
00550 STANDARD_TYPE_DOUBLE);
00551 regRefs[1] = new RegisterRef<float>(
00552 RegisterReference::EInput, 0,
00553 STANDARD_TYPE_REAL);
00554 c.appendRegRef(regRefs[0]);
00555 c.appendRegRef(regRefs[1]);
00556 c.bind();
00557
00558
00559 ExtendedInstruction *pInstr = pDef->createInstruction(regRefs);
00560 assert(pInstr != NULL);
00561
00562 c.appendInstruction(pInstr);
00563 c.exec();
00564 c.printOutput();
00565 double d;
00566 c.getOutput(0, d);
00567 cout << d << endl;
00568 assert(fabs(expected - d) < 0.0001);
00569 };
00570
00571
00572 void testConvertFloatToIntTypes(const char * const str, float val, int expected)
00573 {
00574 printTestHeader("testConvertFloatToIntTypes()");
00575 ExtendedInstructionTable table;
00576 vector<StandardTypeDescriptorOrdinal> parameterTypes;
00577
00578 parameterTypes.resize(2);
00579 parameterTypes[0] = StandardTypeDescriptor::fromString(str);
00580 parameterTypes[1] = STANDARD_TYPE_REAL;
00581 table.add(
00582 "convert",
00583 parameterTypes,
00584 (ExtendedInstruction2<int, float>*) NULL,
00585 &convertFloatToInt);
00586
00587 string s("convert(");
00588 s += str;
00589 s += ",r)";
00590 cout << s << endl;
00591 ExtendedInstructionDef *pDef = table[s];
00592 assert(pDef != NULL);
00593 assert(pDef->getName() == string("convert"));
00594 assert(pDef->getParameterTypes().size() == 2);
00595
00596 ExtendedInstructionDef *pNonExistentDef = table["convert(d,r)"];
00597 assert(pNonExistentDef == NULL);
00598
00599 DynamicParamManager dpm;
00600 TestCalculator c(&dpm, true, pDef);
00601 c.setInput(0, &val);
00602
00603 vector<RegisterReference *> regRefs(2);
00604 regRefs[0] = new RegisterRef<int>(
00605 RegisterReference::EOutput, 0,
00606 STANDARD_TYPE_INT_32);
00607 regRefs[1] = new RegisterRef<float>(
00608 RegisterReference::EInput, 0,
00609 STANDARD_TYPE_REAL);
00610 c.appendRegRef(regRefs[0]);
00611 c.appendRegRef(regRefs[1]);
00612 c.bind();
00613
00614
00615 ExtendedInstruction *pInstr = pDef->createInstruction(regRefs);
00616 assert(pInstr != NULL);
00617
00618 c.appendInstruction(pInstr);
00619 c.exec();
00620 c.printOutput();
00621 int d;
00622 c.getOutput(0, d);
00623 cout << d << endl;
00624 assert(expected == d);
00625 };
00626
00627 void testConvertIntTypesToFloat(const char * const str, int val, float expected)
00628 {
00629 printTestHeader("testConvertIntTypesToFloat()");
00630 ExtendedInstructionTable table;
00631 vector<StandardTypeDescriptorOrdinal> parameterTypes;
00632
00633 parameterTypes.resize(2);
00634 parameterTypes[0] = STANDARD_TYPE_REAL;
00635 parameterTypes[1] = StandardTypeDescriptor::fromString(str);
00636 table.add(
00637 "convert",
00638 parameterTypes,
00639 (ExtendedInstruction2<float, int>*) NULL,
00640 &convertIntToFloat);
00641
00642 string s("convert(r,");
00643 s += str;
00644 s += ")";
00645 cout << s << endl;
00646 ExtendedInstructionDef *pDef = table[s];
00647 assert(pDef != NULL);
00648 assert(pDef->getName() == string("convert"));
00649 assert(pDef->getParameterTypes().size() == 2);
00650
00651 DynamicParamManager dpm;
00652 TestCalculator c(&dpm, true, pDef);
00653 c.setInput(0, &val);
00654
00655 vector<RegisterReference *> regRefs(2);
00656 regRefs[0] = new RegisterRef<float>(
00657 RegisterReference::EOutput, 0,
00658 STANDARD_TYPE_REAL);
00659 regRefs[1] = new RegisterRef<int>(
00660 RegisterReference::EInput, 0,
00661 STANDARD_TYPE_INT_32);
00662 c.appendRegRef(regRefs[0]);
00663 c.appendRegRef(regRefs[1]);
00664 c.bind();
00665
00666
00667 ExtendedInstruction *pInstr = pDef->createInstruction(regRefs);
00668 assert(pInstr != NULL);
00669
00670 c.appendInstruction(pInstr);
00671 c.exec();
00672 c.printOutput();
00673 float f;
00674 c.getOutput(0, f);
00675 cout << f << endl;
00676 assert(expected == f);
00677 };
00678
00679 void testConvertDecimal(const char * const str, int val, int exp, int expected)
00680 {
00681 printTestHeader("testConvertDecimal()");
00682 ExtendedInstructionTable table;
00683 vector<StandardTypeDescriptorOrdinal> parameterTypes;
00684
00685 parameterTypes.resize(3);
00686 parameterTypes[0] = StandardTypeDescriptor::fromString(str);
00687 parameterTypes[1] = StandardTypeDescriptor::fromString(str);
00688 parameterTypes[2] = STANDARD_TYPE_INT_8;
00689 table.add(
00690 "convert",
00691 parameterTypes,
00692 (ExtendedInstruction3<int, int, int>*) NULL,
00693 &convertDecimal);
00694
00695 string s("convert(");
00696 s += str;
00697 s += ",";
00698 s += str;
00699 s += ",";
00700 s += "s1";
00701 s += ")";
00702 cout << s << endl;
00703 ExtendedInstructionDef *pDef = table[s];
00704 assert(pDef != NULL);
00705 assert(pDef->getName() == string("convert"));
00706 assert(pDef->getParameterTypes().size() == 3);
00707
00708 DynamicParamManager dpm;
00709 TestCalculator c(&dpm, true, pDef);
00710 c.setInput(0, &val);
00711 c.setInput(1, &exp);
00712
00713 vector<RegisterReference *> regRefs(3);
00714 regRefs[0] = new RegisterRef<int>(
00715 RegisterReference::EOutput, 0,
00716 STANDARD_TYPE_INT_32);
00717 regRefs[1] = new RegisterRef<int>(
00718 RegisterReference::EInput, 0,
00719 STANDARD_TYPE_INT_32);
00720 regRefs[2] = new RegisterRef<int>(
00721 RegisterReference::EInput, 1,
00722 STANDARD_TYPE_INT_32);
00723 c.appendRegRef(regRefs[0]);
00724 c.appendRegRef(regRefs[1]);
00725 c.appendRegRef(regRefs[2]);
00726 c.bind();
00727
00728
00729 ExtendedInstruction *pInstr = pDef->createInstruction(regRefs);
00730 assert(pInstr != NULL);
00731
00732 c.appendInstruction(pInstr);
00733 c.exec();
00734 c.printOutput();
00735 int i;
00736 c.getOutput(0, i);
00737
00738 assert(abs(expected - i)<0.00001);
00739 };
00740
00741 void testConvertStringToExactNumber(const char *str, int expected)
00742 {
00743 printTestHeader("testConvertStringToExactNumber()");
00744 ExtendedInstructionTable table;
00745 vector<StandardTypeDescriptorOrdinal> parameterTypes;
00746
00747 parameterTypes.resize(2);
00748 parameterTypes[0] = STANDARD_TYPE_INT_32;
00749 parameterTypes[1] = STANDARD_TYPE_VARCHAR;
00750
00751 table.add(
00752 "convert",
00753 parameterTypes,
00754 (ExtendedInstruction2<int32_t, char *>*) NULL,
00755 &convertStringToExactNumber);
00756
00757
00758 ExtendedInstructionDef *pDef = table["convert(s4,vc)"];
00759 assert(pDef != NULL);
00760 assert(pDef->getName() == string("convert"));
00761 assert(pDef->getParameterTypes().size() == 2);
00762
00763
00764 DynamicParamManager dpm;
00765 TestCalculator c(&dpm, true, pDef);
00766 c.setInput(0, str, strlen(str));
00767
00768
00769 vector<RegisterReference *> regRefs(2);
00770 regRefs[0] = new RegisterRef<int32_t>(
00771 RegisterReference::EOutput, 0,
00772 STANDARD_TYPE_INT_32);
00773 regRefs[1] = new RegisterRef<char *>(
00774 RegisterReference::EInput, 0,
00775 STANDARD_TYPE_VARCHAR);
00776 c.appendRegRef(regRefs[0]);
00777 c.appendRegRef(regRefs[1]);
00778 c.bind();
00779
00780
00781
00782 ExtendedInstruction *pInstr = pDef->createInstruction(regRefs);
00783 assert(pInstr != NULL);
00784
00785 c.appendInstruction(pInstr);
00786 c.exec();
00787 c.printOutput();
00788 int i;
00789 c.getOutput(0, i);
00790 assert(i == expected);
00791 cout << i << endl;
00792 }
00793
00794 #if 0
00795
00796 void testConvertExactNumberToString(int num, char *expected)
00797 {
00798 printTestHeader("testConvertExactNumberToString()");
00799 ExtendedInstructionTable table;
00800 vector<StandardTypeDescriptorOrdinal> parameterTypes;
00801
00802 parameterTypes.resize(2);
00803 parameterTypes[0] = STANDARD_TYPE_VARCHAR;
00804 parameterTypes[1] = STANDARD_TYPE_INT_32;
00805
00806 table.add(
00807 "convert",
00808 parameterTypes,
00809 (ExtendedInstruction2<char *, int32_t>*) NULL,
00810 &convertExactNumberToString);
00811
00812
00813 ExtendedInstructionDef *pDef = table["convert(vc,s4)"];
00814 assert(pDef != NULL);
00815 assert(pDef->getName() == string("convert"));
00816 assert(pDef->getParameterTypes().size() == 2);
00817
00818
00819 DynamicParamManager dpm;
00820 TestCalculator c(&dpm, true, pDef);
00821 c.setInput(0, &num);
00822 int destLen = strlen(expected);
00823 char *buf = new char[destLen*2];
00824 memset(buf, 'X', destLen*2);
00825 c.setOutput(0, buf, destLen*2, destLen*2);
00826
00827
00828 vector<RegisterReference *> regRefs(2);
00829 regRefs[0] = new RegisterRef<int32_t>(
00830 RegisterReference::EOutput, 0,
00831 STANDARD_TYPE_VARCHAR);
00832 regRefs[1] = new RegisterRef<char *>(
00833 RegisterReference::EInput, 0,
00834 STANDARD_TYPE_INT_32);
00835 c.appendRegRef(regRefs[0]);
00836 c.appendRegRef(regRefs[1]);
00837 c.bind();
00838
00839
00840
00841 ExtendedInstruction *pInstr = pDef->createInstruction(regRefs);
00842 assert(pInstr != NULL);
00843
00844 c.appendInstruction(pInstr);
00845 c.exec();
00846 c.printOutput();
00847 char *outP;
00848 c.getOutputP(0, outP);
00849 assert(outP == buf);
00850 assert(!strncmp(outP, expected, destLen));
00851 outP[destLen] = 0;
00852 cout << outP << endl;
00853 }
00854 #endif
00855 void testStringToApproximateNumber(char *str, float expected)
00856 {
00857 }
00858 void testApproximateNumberToString(float expected, char *str)
00859 {
00860 }
00861 void testStringToDate(char *str, long long expected)
00862 {
00863 }
00864 void testDateToString(long long d, char *expected)
00865 {
00866 }
00867
00868
00869
00870
00871 int main(int argc, char *argv[])
00872 {
00873 ProgramName = argv[0];
00874 testConvertDoubleToFloat((double) 100.33, (float) 100.33);
00875 testConvertFloatToDouble((float) 33.3378, (double) 33.3378);
00876 testConvertFloatToIntTypes("s1",(float) 45.65, 45);
00877 testConvertFloatToIntTypes("u1",(float) 45.65, 45);
00878 testConvertFloatToIntTypes("s2",(float) 45.65, 45);
00879 testConvertFloatToIntTypes("u2",(float) 45.65, 45);
00880 testConvertFloatToIntTypes("s4",(float) 45.65, 45);
00881 testConvertFloatToIntTypes("u4",(float) 45.65, 45);
00882 testConvertFloatToIntTypes("s8",(float) 45.65, 45);
00883 testConvertFloatToIntTypes("u8",(float) 45.65, 45);
00884 testConvertIntTypesToFloat("s1", 4565, (float) 4565);
00885 testConvertIntTypesToFloat("u1", 4565, (float) 4565);
00886 testConvertIntTypesToFloat("s2", 4565, (float) 4565);
00887 testConvertIntTypesToFloat("u2", 4565, (float) 4565);
00888 testConvertIntTypesToFloat("s4", 4565, (float) 4565);
00889 testConvertIntTypesToFloat("u4", 4565, (float) 4565);
00890 testConvertIntTypesToFloat("s8", 4565, (float) 4565);
00891 testConvertIntTypesToFloat("u8", 4565, (float) 4565);
00892 testConvertDecimal("s2", 123, 3, 123000);
00893
00894 testConvertStringToExactNumber("123", 123);
00895
00896 printf("all tests passed\n");
00897 exit(0);
00898 }
00899
00900 boost::unit_test_framework::test_suite *init_unit_test_suite(int,char **)
00901 {
00902 return NULL;
00903 }
00904
00905