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 "Parameter.h"
00026
00027 namespace cmlabs {
00028
00029
00030
00031
00032
00033 Parameter::Parameter(const JString& parametername, const JString& type, const Collection& collValues) {
00034 name = parametername;
00035 valueType = type;
00036 values.removeAll();
00037 values.copyAll(collValues);
00038 maxValue = minValue = NOVALUE;
00039 def = current = 0;
00040 step = 1;
00041 }
00042
00043 Parameter::Parameter(const JString& parametername, const JString& type, const JString& val, const JString& defaultVal) {
00044 name = parametername;
00045 valueType = type;
00046 value = val;
00047 if (defaultVal.length() > 0)
00048 defaultValue = defaultVal;
00049 else
00050 defaultValue = val;
00051 maxValue = minValue = NOVALUE;
00052 def = current = 0;
00053 step = 1;
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 Parameter::Parameter(const JString& parametername, const JString& type) {
00074 name = parametername;
00075 valueType = type;
00076 maxValue = minValue = NOVALUE;
00077 step = 1;
00078 }
00079
00080 Parameter::Parameter(const JString& xml) {
00081 valueType = "String";
00082 def = current = 0;
00083 maxValue = minValue = NOVALUE;
00084 step = 1;
00085 fromXML(xml);
00086 }
00087
00088 Parameter::Parameter(XMLNode* node) {
00089 valueType = "String";
00090 def = current = 0;
00091 maxValue = minValue = NOVALUE;
00092 step = 1;
00093 fromXML(node);
00094 }
00095
00096
00097
00098
00099 Object* Parameter::clone() const {
00100 Parameter* parameter = new Parameter(name, valueType);
00101 *parameter = *this;
00102 parameter->locked = false;
00103 return (Object*) parameter;
00104 }
00105
00106 Parameter::~Parameter() {
00107 values.removeAll();
00108 }
00109
00110
00111 unsigned long Parameter::getPayloadSize() const {
00112 return name.length() + value.length() + defaultValue.length() + parameterType.length() +
00113 notify.length() + values.getPayloadSize();
00114 }
00115
00116 JString Parameter::print() {
00117 JString minmax = "";
00118 if (minValue != NOVALUE)
00119 minmax = JString::format(" min=\"%f\"", minValue);
00120 if (maxValue != NOVALUE)
00121 minmax += JString::format(" max=\"%f\"", maxValue);
00122
00123 if (values.getCount() > 0) {
00124 return JString::format("Parameter name=\"%s\" type=\"%s\" value=\"%s\" default=\"%s\" step=\"%f\"%s>\n%s",
00125 (char*) getName().xmlStringEncode(), (char*) getType().xmlStringEncode(), (char*) getString().xmlStringEncode(), (char*) defaultValue.xmlStringEncode(),
00126 step, (char*) minmax, (char*) values.printListLine("\n", " = ", "'"));
00127 }
00128 else {
00129 return JString::format("Parameter name=\"%s\" type=\"%s\" value=\"%s\" default=\"%s\" step=\"%f\"%s",
00130 (char*) getName().xmlStringEncode(), (char*) getType().xmlStringEncode(), (char*) getString().xmlStringEncode(), (char*) defaultValue.xmlStringEncode(),
00131 step, (char*) minmax);
00132 }
00133 }
00134
00135
00136
00137
00138
00139
00140 JString Parameter::toXML() {
00141
00142 JString minmax = "";
00143 if (minValue != NOVALUE)
00144 minmax = JString::format(" min=\"%f\"", minValue);
00145 if (maxValue != NOVALUE)
00146 minmax += JString::format(" max=\"%f\"", maxValue);
00147 if (notify.length() > 0)
00148 minmax += JString::format(" notify=\"%s\"", (char*) notify.xmlStringEncode());
00149
00150 JString xml;
00151 if (values.getCount() > 0) {
00152 xml = JString::format("<parameter name=\"%s\" type=\"%s\" value=\"%s\" default=\"%s\" step=\"%f\"%s>\n%s</parameter>",
00153 (char*) getName().xmlStringEncode(), (char*) getType().xmlStringEncode(), (char*) getString().xmlStringEncode(), (char*) defaultValue.xmlStringEncode(),
00154 step, (char*) minmax, (char*) values.toXML().indentXML());
00155 }
00156 else {
00157 xml = JString::format("<parameter name=\"%s\" type=\"%s\" value=\"%s\" default=\"%s\" step=\"%f\"%s />", (char*) getName().xmlStringEncode(),
00158 (char*) getType().xmlStringEncode(), (char*) getString().xmlStringEncode(), (char*) defaultValue.xmlStringEncode(), step, (char*) minmax);
00159 }
00160 return xml;
00161 }
00162
00163 bool Parameter::fromXML(const JString& xml) {
00164
00165 if (xml.length() == 0)
00166 return false;
00167
00168 XMLParser* xmlParser = new XMLParser();
00169 xmlParser->parse(xml);
00170 bool ret = fromXML(xmlParser->getRootNode());
00171 delete(xmlParser);
00172 return ret;
00173 }
00174
00175 bool Parameter::fromXML(XMLNode* node) {
00176
00177 if (node == NULL)
00178 return false;
00179
00180
00181
00182 name = node->getAttribute("name");
00183 setType(node->findAttr("type"));
00184 value = node->getAttribute("value");
00185 notify = node->getAttribute("notify");
00186 if (node->hasAttribute("default"))
00187 defaultValue = node->getAttribute("default");
00188 else
00189 defaultValue = value;
00190 if (node->hasAttribute("step"))
00191 step = node->getAttribute("step").toDouble();
00192 if (node->hasAttribute("min"))
00193 minValue = node->getAttribute("min").toDouble();
00194 if (node->hasAttribute("max"))
00195 maxValue = node->getAttribute("max").toDouble();
00196
00197 if (value.length() == 0)
00198 value = defaultValue;
00199 else if (defaultValue.length() == 0)
00200 defaultValue = value;
00201
00202 XMLNode* subNode = node->getChildNode("collection");
00203 if (subNode != NULL)
00204 values.fromXML(subNode);
00205 else
00206 values.removeAll();
00207
00208 return true;
00209 }
00210
00211
00212
00213
00214
00215
00216 bool Parameter::set(const JString& val) {
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 if (valueType.equalsIgnoreCase("Integer")) {
00227 return setInteger(val.toInt());
00228 }
00229 else if (valueType.equalsIgnoreCase("Double")) {
00230 return setDouble(val.toDouble());
00231 }
00232 else if (valueType.equalsIgnoreCase("Pointer")) {
00233 return setPointer(val.toPointer());
00234 }
00235 else {
00236 return setString(val);
00237 }
00238 }
00239
00240 bool Parameter::setType(const JString& type) {
00241 valueType = type;
00242 return true;
00243 }
00244
00245 bool Parameter::setMinMax(double min, double max) {
00246
00247
00248
00249
00250
00251 minValue = min;
00252 maxValue = max;
00253
00254 return true;
00255 }
00256
00257 bool Parameter::setString(const JString& val) {
00258
00259 if (valueType.length() == 0)
00260 valueType = "String";
00261
00262 if (!valueType.equalsIgnoreCase("String")) {
00263 if (DEBUGLEVEL(STATUS)) {
00264 printf("[Parameter] Setting non-string param to string");
00265 }
00266 return false;
00267 }
00268
00269
00270 if (values.getCount() == 0) {
00271 value = val;
00272 }
00273 else {
00274 if (!values.contains(val))
00275 return false;
00276 current = values.getPos(val);
00277 }
00278 return true;
00279 }
00280
00281 bool Parameter::setInteger(int val) {
00282
00283 if (valueType.length() == 0)
00284 valueType = "Integer";
00285
00286 if (!valueType.equalsIgnoreCase("Integer")) {
00287 if (DEBUGLEVEL(STATUS)) {
00288 printf("[Parameter] Setting non-integer param to integer");
00289 }
00290 return false;
00291 }
00292
00293
00294 if (values.getCount() == 0) {
00295 if ( (minValue != NOVALUE) && (maxValue != NOVALUE) && ( (val < minValue) || (val > maxValue) ) ) {
00296 return false;
00297 }
00298 value = JString(val);
00299 }
00300 else {
00301 if (!values.contains(JString(val))) {
00302 return false;
00303 }
00304 current = values.getPos(JString(val));
00305 }
00306 return true;
00307 }
00308
00309 bool Parameter::setDouble(double val) {
00310
00311 if (valueType.length() == 0)
00312 valueType = "Double";
00313
00314 if (!valueType.equalsIgnoreCase("Double")) {
00315 if (DEBUGLEVEL(STATUS)) {
00316 printf("[Parameter] Setting non-double param to double");
00317 }
00318 return false;
00319 }
00320
00321
00322 if (values.getCount() == 0) {
00323 if ( (minValue != NOVALUE) && (maxValue != NOVALUE) && ( (val < minValue) || (val > maxValue) ) )
00324 return false;
00325 value = JString(val);
00326 }
00327 else {
00328 if (!values.contains(JString(val)))
00329 return false;
00330 current = values.getPos(JString(val));
00331 }
00332 return true;
00333 }
00334
00335 bool Parameter::setPointer(void* val) {
00336
00337 if (valueType.length() == 0)
00338 valueType = "Pointer";
00339
00340 if (!valueType.equalsIgnoreCase("Pointer")) {
00341 if (DEBUGLEVEL(STATUS)) {
00342 printf("[Parameter] Setting non-pointer param to pointer");
00343 }
00344 return false;
00345 }
00346
00347 value = JString(val);
00348 return true;
00349 }
00350
00351
00352
00353
00354
00355
00356
00357 JString Parameter::getType() {
00358 return valueType;
00359 }
00360
00361 JString Parameter::getName() {
00362 return name;
00363 }
00364
00365 int Parameter::getInteger() {
00366
00367
00368
00369
00370 if (values.getCount() == 0)
00371 return value.toInt();
00372 else {
00373 if (current < 0) return 0;
00374 if (!valueType.equals("Integer")) return 0;
00375 return values.get(current).toInt();
00376 }
00377 }
00378
00379 double Parameter::getDouble() {
00380
00381
00382
00383
00384 if (values.getCount() == 0)
00385 return value.toDouble();
00386 else {
00387 if (current < 0) return 0;
00388 if (!valueType.equals("Double")) return 0;
00389 return values.get(current).toDouble();
00390 }
00391 }
00392
00393 JString Parameter::getString() {
00394
00395
00396
00397
00398 if (values.getCount() == 0)
00399 return value;
00400 else {
00401 if (current < 0) return "";
00402 return values.get(current);
00403 }
00404 }
00405
00406 JString Parameter::getAsString() {
00407
00408 if (values.getCount() == 0)
00409 return value;
00410 else {
00411 if (current < 0) return "";
00412 return values.get(current);
00413 }
00414 }
00415
00416 void* Parameter::getPointer() {
00417
00418
00419
00420
00421 return (void*) value.toPointer();
00422 }
00423
00424
00425 bool Parameter::addItem(const JString& value) {
00426 if (values.getCount() == 0)
00427 return false;
00428 int pos = values.getPos(value);
00429 if (pos >= 0)
00430 return true;
00431 else
00432 return values.add(value);
00433 }
00434
00435 bool Parameter::removeItem(const JString& value) {
00436 if (values.getCount() < 2)
00437 return false;
00438 int pos = values.getPos(value);
00439 if (pos < 0)
00440 return true;
00441 else {
00442 if ((current == pos) && (current > 0)) {
00443 current--;
00444 }
00445 return values.remove(pos);
00446 }
00447 }
00448
00449
00450
00451 bool Parameter::reset() {
00452 current = def;
00453 value = defaultValue;
00454 return true;
00455 }
00456
00457 bool Parameter::increment(int steps) {
00458
00459 if (valueType.equalsIgnoreCase("Integer")) {
00460 return setInteger(value.toInt() + (int)(step*steps));
00461 }
00462 if (valueType.equalsIgnoreCase("Double")) {
00463 return setDouble(value.toDouble() + (step*steps));
00464 }
00465 if (values.getCount() == 0)
00466 return true;
00467
00468 if (current < 0) return false;
00469
00470 if ( (current+steps) < (values.length()-1) ) {
00471 current += steps;
00472 return true;
00473 }
00474 else
00475 return false;
00476 }
00477
00478 bool Parameter::decrement(int steps) {
00479 if (valueType.equalsIgnoreCase("Integer")) {
00480 return setInteger(value.toInt() - (int)(step*steps));
00481 }
00482 if (valueType.equalsIgnoreCase("Double")) {
00483 return setDouble(value.toDouble() - (step*steps));
00484 }
00485 if (values.getCount() == 0)
00486 return true;
00487
00488 if (current < 0) return false;
00489
00490 if (current-steps >= 0) {
00491 current -= steps;
00492 return true;
00493 }
00494 else
00495 return false;
00496 }
00497
00498
00499 JString Parameter::getParameterValueFromCollection(ObjectDictionary* parameters, const JString& name) {
00500 if (parameters == NULL)
00501 return "";
00502 Parameter* param = (Parameter*) parameters->getIgnoreCase(name);
00503 if (param == NULL)
00504 return "";
00505 return param->value;
00506 }
00507
00508 ObjectDictionary* Parameter::getParameterCollectionFromNode(XMLNode* node) {
00509
00510 if (node == NULL)
00511 return NULL;
00512
00513 ObjectCollection* children = node->getChildTags();
00514 if ( (children == NULL) || (children->getCount() == 0) )
00515 return NULL;
00516
00517 ObjectDictionary* parameters = new ObjectDictionary();
00518 XMLNode* xmlNode;
00519
00520 JString name, source;
00521 for (int n=0; n<children->getCount(); n++) {
00522 xmlNode = (XMLNode*) children->get(n);
00523 if (xmlNode != NULL) {
00524
00525 name = xmlNode->getAttribute("name");
00526 if (name.length() > 0) {
00527 parameters->put(name, new Parameter(xmlNode));
00528 }
00529 }
00530
00531 }
00532
00533 if (parameters->getCount() == 0) {
00534 delete(parameters);
00535 parameters = NULL;
00536 }
00537
00538 return parameters;
00539 }
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555 bool Parameter::unitTest() {
00556
00557 JString xml = "<parameter name=\"ProgDetCriteria\" type=\"String\" value=\"if obj.x > 1 and obj.x < 3 then status = true else status = false end\"/>";
00558
00559 Parameter* p = new Parameter(xml);
00560
00561 JString xml2 = p->toXML().trimCTRL();
00562
00563 p->fromXML(xml2);
00564
00565 if (!p->getString().equalsIgnoreCase("if obj.x > 1 and obj.x < 3 then status = true else status = false end")) {
00566 addUnitTestLog(JString::format("Parameter XML and toXML did not match\n%s\n%s\n", (char*) xml, (char*) xml2));
00567 return false;
00568 }
00569 delete(p);
00570
00571 Collection oc;
00572
00573 oc.add("Test0");
00574 oc.add("Test1");
00575 oc.add("Test2");
00576 oc.add("Test3");
00577 oc.add("Test4");
00578 oc.add("Test5");
00579 oc.add("Test6");
00580 oc.add("Test7");
00581 oc.add("Test8");
00582 oc.add("Test9");
00583 oc.add("Test10");
00584
00585 Parameter* parameter = new Parameter("MyParam", "String", oc);
00586
00587 if (parameter->values.getCount() != 11)
00588 return false;
00589
00590 if (!parameter->set("Test6"))
00591 return false;
00592
00593 if (!parameter->getString().equals("Test6"))
00594 return false;
00595
00596 if (parameter->set("TestBla"))
00597 return false;
00598
00599 if (!parameter->getString().equals("Test6"))
00600 return false;
00601
00602 if (!parameter->reset())
00603 return false;
00604
00605 JString s = parameter->getString();
00606 if (!s.equals("Test0"))
00607 return false;
00608
00609 delete(parameter);
00610
00611
00612 parameter = new Parameter("<parameter name=\"ProgDetCriteria\" type=\"Integer\" value=\"0\" default=\"6\" step=\"2\" min=\"0\" max=\"10\"/>");
00613
00614 int n;
00615 if ( (n = parameter->getInteger()) != 0)
00616 return false;
00617
00618 if (!parameter->reset())
00619 return false;
00620 if ( (n = parameter->getInteger()) != 6)
00621 return false;
00622
00623 if (!parameter->increment(2))
00624 return false;
00625 if ( (n = parameter->getInteger()) != 10)
00626 return false;
00627
00628 if (!parameter->decrement(4))
00629 return false;
00630 if ( (n = parameter->getInteger()) != 2)
00631 return false;
00632
00633 if (parameter->set(12))
00634 return false;
00635 if ( (n = parameter->getInteger()) != 2)
00636 return false;
00637
00638 delete(parameter);
00639
00640 return true;
00641 }
00642
00643
00644 }