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
00026
00027
00028
00029
00030 #include "config.h"
00031
00032 #include "DataBox.hpp"
00033
00034 #include <iostream>
00035 #include <sstream>
00036 #include <boost/pointer_cast.hpp>
00037
00038 #include "DataFactory.hpp"
00039 #include "DataType.hpp"
00040 #include "Double.hpp"
00041 #include "Integer.hpp"
00042 #include "String.hpp"
00043 #include "Exceptions/UnexpectedDataTypeException.hpp"
00044 #include <XmlAttribute.hpp>
00045 #include <XmlAttributeVector.hpp>
00046
00047 #include <Exception.hpp>
00048
00049
00050
00051 using namespace mermaid::support::data;
00052
00053 using boost::static_pointer_cast;
00054
00055 using mermaid::support::errorhandling::Exception;
00056 using mermaid::support::xml::XmlAttribute;
00057 using mermaid::support::xml::XmlAttributeVector;
00058 using mermaid::support::data::exceptions::UnexpectedDataTypeException;
00059
00060
00061
00062 DataBox::DataBox() : DataValue()
00063 {
00064 type_ = DATABOX;
00065 };
00066
00067
00068
00069 DataBox::DataBox (shared_ptr<DataStructureDescription> dsd) : DataValue()
00070 {
00071 type_ = DATABOX;
00072 dataStructureDescription_ = dsd;
00073 valueVector_ = DataFactory::buildDataValueVector();
00074
00075 std::vector<shared_ptr<DataItemDescription> > itemDescriptions = dsd->getItemDescriptionVector();
00076
00077
00078 std::vector<shared_ptr<DataItemDescription> >::iterator itemIt;
00079
00080 for (itemIt = itemDescriptions.begin(); itemIt != itemDescriptions.end(); itemIt++) {
00081 shared_ptr<DataItemDescription> did = *itemIt;
00082
00083 std::string itemName = did->getItemName();
00084 std::string itemType = did->getItemType();
00085 bool isArray = did->isItemArray();
00086 bool isDynamic = ! (did->isArrayStatic());
00087 int staticArraySize = did->getStaticArraySize();
00088
00089
00090
00091 if (isArray == false) {
00092 if (itemType.compare ("integer") == 0) {
00093 this->addInteger (itemName);
00094 }
00095 else if (itemType.compare ("double") == 0) {
00096 this->addDouble (itemName);
00097 }
00098 else if (itemType.compare ("string") == 0) {
00099 this->addString (itemName);
00100 }
00101 else {
00102
00103 try {
00104 this->addDataBox (itemName, itemType);
00105 }
00106 catch (Exception &e) {
00107 throw Exception ("DataBox::DataBox(DataStructureDescription) : unknown data item type: " + itemType);
00108 }
00109 }
00110 }
00111 else {
00112 if (isDynamic == true) {
00113 if (itemType.compare ("integer") == 0) {
00114 this->addDynamicIntegerArray (itemName);
00115 }
00116 else if (itemType.compare ("double") == 0) {
00117 this->addDynamicDoubleArray (itemName);
00118 }
00119 else if (itemType.compare ("string") == 0) {
00120 this->addDynamicStringArray (itemName);
00121 }
00122 else {
00123 this->addDynamicDataBoxArray (itemName, itemType);
00124 }
00125
00126 }
00127 else {
00128
00129 if (itemType.compare ("integer") == 0) {
00130 this->addStaticIntegerArray (itemName, staticArraySize);
00131 }
00132 else if (itemType.compare ("double") == 0) {
00133 this->addStaticDoubleArray (itemName, staticArraySize);
00134 }
00135 else if (itemType.compare ("string") == 0) {
00136 this->addStaticStringArray (itemName, staticArraySize);
00137 }
00138 else {
00139
00140 this->addStaticDataBoxArray (itemName, itemType, staticArraySize);
00141 }
00142 }
00143 }
00144 }
00145 };
00146
00147
00148
00149 DataBox::DataBox (const DataBox &dbox) : DataValue()
00150 {
00151 type_ = DATABOX;
00152
00153 throw Exception ("DataBox:DataBox : copt constructor not supported");
00154
00155
00156
00157
00158 };
00159
00160
00161
00162 DataBox * DataBox::clone()
00163 {
00164 return new DataBox (*this);
00165 };
00166
00167
00168
00169 std::string DataBox::getBoxStructureName() const
00170 {
00171 return dataStructureDescription_->getName();
00172 };
00173
00174
00175
00176 shared_ptr<DataValue> DataBox::getValue (std::string valueName) const
00177 {
00178 std::map<std::string, shared_ptr<DataValue> >::const_iterator it = nameToPtrMap_.find (valueName);
00179
00180 if (it == nameToPtrMap_.end()) {
00181 throw Exception ("DataBox::getValue : request for an unknown name: " + valueName);
00182 }
00183
00184 shared_ptr<DataValue> dv = (*it).second;
00185
00186 if (dv == false) {
00187 throw Exception ("DataBox::getValue : request for an unknown name: " + valueName);
00188 }
00189
00190 return dv;
00191 };
00192
00193
00194
00195 shared_ptr<DataValueVector> DataBox::getDataValueVector() const
00196 {
00197 return valueVector_;
00198 };
00199
00200
00201
00202 int DataBox::getInteger (std::string name) const
00203 {
00204 shared_ptr<DataValue> dv = getValue (name);
00205
00206 if (dv->getType() != INTEGER) {
00207 throw Exception ("DataBox::getInteger : value is not an integer");
00208 }
00209
00210 return ( (Integer*) dv.get())->getValue();
00211 };
00212
00213
00214
00215 shared_ptr<IntegerArray> DataBox::getIntegerArray (std::string name) const
00216 {
00217 shared_ptr<DataValue> dv = getValue (name);
00218
00219 if (dv->getType() != INTEGERARRAY) {
00220 throw Exception ("DataBox::getIntegerArray : value is not an integer array");
00221 }
00222
00223 return static_pointer_cast<IntegerArray> (dv);
00224 };
00225
00226
00227
00228 double DataBox::getDouble (std::string name) const
00229 {
00230 shared_ptr<DataValue> dv = getValue (name);
00231
00232 if (dv->getType() != DOUBLE) {
00233 throw Exception ("DataBox::getDouble : value is not a double");
00234 }
00235
00236 return ( (Double*) dv.get())->getValue();
00237 };
00238
00239
00240
00241 shared_ptr<DoubleArray> DataBox::getDoubleArray (std::string name) const
00242 {
00243 shared_ptr<DataValue> dv = getValue (name);
00244
00245 if (dv->getType() != DOUBLEARRAY) {
00246 throw Exception ("DataBox::getDoubleArray : value is not a double array");
00247 }
00248
00249 return static_pointer_cast<DoubleArray> (dv);
00250
00251 };
00252
00253
00254
00255 std::string DataBox::getString (std::string name) const
00256 {
00257 shared_ptr<DataValue> dv = getValue (name);
00258
00259 if (dv->getType() != STRING) {
00260 throw Exception ("DataBox::getString : value is not a string");
00261 }
00262
00263 return ( (String*) dv.get())->getValue();
00264 };
00265
00266
00267
00268 shared_ptr<StringArray> DataBox::getStringArray (std::string name) const
00269 {
00270 shared_ptr<DataValue> dv = getValue (name);
00271
00272 if (dv->getType() != STRINGARRAY) {
00273 throw Exception ("DataBox::getStringArray : value is not a string array");
00274 }
00275
00276 return static_pointer_cast<StringArray> (dv);
00277 };
00278
00279
00280
00281 shared_ptr<DataBox> DataBox::getDataBox (std::string name) const
00282 {
00283 shared_ptr<DataValue> dv = getValue (name);
00284
00285 if (dv->getType() != DATABOX) {
00286 throw Exception ("DataBox::getDataBox : value is not a DataBox");
00287 }
00288
00289 return static_pointer_cast<DataBox> (dv);
00290 };
00291
00292
00293
00294 shared_ptr<DataBoxArray> DataBox::getDataBoxArray (std::string name) const
00295 {
00296 shared_ptr<DataValue> dv = getValue (name);
00297
00298 if (dv->getType() != DATABOXARRAY) {
00299 throw Exception ("DataBox::getDataBoxArray : value is not a DataBoxArray");
00300 }
00301
00302 return static_pointer_cast<DataBoxArray> (dv);
00303 };
00304
00305
00306
00307 void DataBox::setInteger (std::string name, int value)
00308 {
00309 shared_ptr<DataValue> dv = getValue (name);
00310
00311 if (dv == false) {
00312 throw Exception ("DataBox::setInteger : name not recognised");
00313 }
00314
00315 if (dv->getType() != INTEGER) {
00316 throw Exception ("DataBox::setInteger : value is not an integer");
00317 }
00318
00319 ( (Integer*) dv.get())->setValue (value);
00320 };
00321
00322
00323
00324 void DataBox::setDouble (std::string name, double value)
00325 {
00326 shared_ptr<DataValue> dv = getValue (name);
00327
00328 if (dv == false) {
00329 throw Exception ("DataBox::setDouble : name not recognised");
00330 }
00331
00332 if (dv->getType() != DOUBLE) {
00333 throw Exception ("DataBox::setDouble: value is not a double");
00334 }
00335
00336 ( (Double*) dv.get())->setValue (value);
00337 };
00338
00339
00340
00341 void DataBox::setString (std::string name, std::string value)
00342 {
00343 shared_ptr<DataValue> dv = getValue (name);
00344
00345 if (dv == false) {
00346 throw Exception ("DataBox::setString: name not recognised");
00347 }
00348
00349 if (dv->getType() != STRING) {
00350 throw Exception ("DataBox::setString: value is not a string");
00351 }
00352
00353 ( (String*) dv.get())->setValue (value);
00354 };
00355
00356
00357
00358 void DataBox::setValueFromString (std::string name, std::string value)
00359 {
00360 shared_ptr<DataValue> dv = getValue (name);
00361
00362 if (dv == false) {
00363 throw Exception ("DataBox::setValueFromString: name not recognised");
00364 }
00365
00366 switch (dv->getType()) {
00367 case INTEGER: {
00368 std::stringstream ss;
00369 ss << value;
00370 int i;
00371 ss >> i;
00372 ( (Integer*) dv.get())->setValue (i);
00373 }
00374 break;
00375
00376 case DOUBLE: {
00377 std::stringstream ss;
00378 ss << value;
00379 double d;
00380 ss >> d;
00381 ( (Double*) dv.get())->setValue (d);
00382 }
00383 break;
00384
00385 case STRING: {
00386 ( (String*) dv.get())->setValue (value);
00387 }
00388 break;
00389
00390 default: {
00391 throw Exception ("DataBox::setValueFromString: setting value for unsupported data type");
00392 }
00393 }
00394 };
00395
00396
00397
00398 void DataBox::addInteger (std::string name, int i)
00399 {
00400
00401 shared_ptr<DataValue> dv = static_pointer_cast<DataValue> (DataFactory::buildInteger (i));
00402 addDataValue (name, dv);
00403 };
00404
00405
00406
00407 shared_ptr<IntegerArray> DataBox::addDynamicIntegerArray (std::string name)
00408 {
00409
00410 shared_ptr<DataValue> dv = DataFactory::buildDynamicIntegerArray();
00411 addDataValue (name, dv);
00412 return static_pointer_cast<IntegerArray> (dv);
00413 };
00414
00415
00416
00417 shared_ptr<IntegerArray> DataBox::addStaticIntegerArray (std::string name, int size)
00418 {
00419
00420 shared_ptr<DataValue> dv = DataFactory::buildStaticIntegerArray (size);
00421 addDataValue (name, dv);
00422 return static_pointer_cast<IntegerArray> (dv);
00423 };
00424
00425
00426
00427 void DataBox::addDouble (std::string name, double d)
00428 {
00429
00430 shared_ptr<DataValue> dv = DataFactory::buildDouble (d);
00431 addDataValue (name, dv);
00432 };
00433
00434
00435
00436 shared_ptr<DoubleArray> DataBox::addDynamicDoubleArray (std::string name)
00437 {
00438
00439 shared_ptr<DataValue> dv = DataFactory::buildDynamicDoubleArray();
00440 addDataValue (name, dv);
00441 return static_pointer_cast<DoubleArray> (dv);
00442 };
00443
00444
00445
00446 shared_ptr<DoubleArray> DataBox::addStaticDoubleArray (std::string name, int size)
00447 {
00448
00449 shared_ptr<DataValue> dv = DataFactory::buildStaticDoubleArray (size);
00450 addDataValue (name, dv);
00451 return static_pointer_cast<DoubleArray> (dv);
00452 };
00453
00454
00455
00456 void DataBox::addString (std::string name, std::string s)
00457 {
00458
00459 shared_ptr<DataValue> dv = DataFactory::buildString (s);
00460 addDataValue (name, dv);
00461 };
00462
00463
00464
00465 shared_ptr<StringArray> DataBox::addDynamicStringArray (std::string name)
00466 {
00467
00468 shared_ptr<DataValue> dv = DataFactory::buildDynamicStringArray();
00469 addDataValue (name, dv);
00470 return static_pointer_cast<StringArray> (dv);
00471 };
00472
00473
00474
00475 shared_ptr<StringArray> DataBox::addStaticStringArray (std::string name, int size)
00476 {
00477
00478 shared_ptr<DataValue> dv = DataFactory::buildStaticStringArray (size);
00479 addDataValue (name, dv);
00480 return static_pointer_cast<StringArray> (dv);
00481 };
00482
00483
00484
00485 void DataBox::addDataBox (std::string name, std::string type)
00486 {
00487
00488 shared_ptr<DataValue> dv = DataFactory::buildDataBox (type);
00489 addDataValue (name, dv);
00490 };
00491
00492
00493
00494 shared_ptr<DataBoxArray> DataBox::addDynamicDataBoxArray (std::string name, std::string type)
00495 {
00496
00497 shared_ptr<DataValue> dv = DataFactory::buildDynamicDataBoxArray (type);
00498 addDataValue (name, dv);
00499 return static_pointer_cast<DataBoxArray> (dv);
00500 };
00501
00502
00503
00504 shared_ptr<DataBoxArray> DataBox::addStaticDataBoxArray (std::string name, std::string type, int size)
00505 {
00506
00507 shared_ptr<DataValue> dv = DataFactory::buildStaticDataBoxArray (type, size);
00508 addDataValue (name, dv);
00509 return static_pointer_cast<DataBoxArray> (dv);
00510 };
00511
00512
00513
00514 void DataBox::addDataValue (std::string name, shared_ptr<DataValue> value)
00515 {
00516 valueVector_->pushBack (value);
00517 nameToPtrMap_[name] = value;
00518 ptrToNameMap_[value] = name;
00519 };
00520
00521
00522
00523 int DataBox::setDataFromValueVector (shared_ptr<DataValueVector> vv, int startPos)
00524 {
00525 std::vector<shared_ptr<DataItemDescription> > itemDescriptionVector = dataStructureDescription_->getItemDescriptionVector();
00526 std::vector<shared_ptr<DataItemDescription> >::iterator itemIt;
00527
00528 int currentValueVectorPos = startPos;
00529
00530 for (itemIt = itemDescriptionVector.begin(); itemIt != itemDescriptionVector.end(); itemIt++) {
00531 shared_ptr<DataItemDescription> itemDesc = *itemIt;
00532
00533 std::string itemName = itemDesc->getItemName();
00534 std::string itemType = itemDesc->getItemType();
00535 bool isArray = itemDesc->isItemArray();
00536 bool isDynamic = ! (itemDesc->isArrayStatic());
00537
00538 if (isArray == false) {
00539 if (itemType.compare ("integer") == 0) {
00540
00541 shared_ptr<DataValue> value = vv->getValue (currentValueVectorPos++);
00542
00543 if (value->getType() != INTEGER) {
00544 throw UnexpectedDataTypeException ("DataBox::setDataFromValueVector : unexpected data type");
00545 }
00546
00547 int i = ( (Integer*) value.get())->getValue();
00548
00549
00550 this->addInteger (itemName, i);
00551 }
00552 else if (itemType.compare ("double") == 0) {
00553
00554 shared_ptr<DataValue> value = vv->getValue (currentValueVectorPos++);
00555
00556 if (value->getType() != DOUBLE) {
00557 throw UnexpectedDataTypeException ("DataBox::setDataFromValueVector : unexpected data type");
00558 }
00559
00560 double d = ( (Double*) value.get())->getValue();
00561
00562 this->addDouble (itemName, d);
00563 }
00564 else if (itemType.compare ("string") == 0) {
00565
00566 shared_ptr<DataValue> value = vv->getValue (currentValueVectorPos++);
00567
00568 if (value->getType() != STRING) {
00569 throw UnexpectedDataTypeException ("DataBox::setDataFromValueVector : unexpected data type");
00570 }
00571
00572 std::string s = ( (String*) value.get())->getValue();
00573
00574 this->addString (itemName, s);
00575 }
00576 else {
00577 shared_ptr<DataBox> b = getDataBox (itemName);
00578 std::string bType = b->dataStructureDescription_->getName();
00579
00580 if (bType.compare (itemType) != 0) {
00581 throw Exception ("DataBox::setDataFromValueVector : child data box not of the correct type");
00582 }
00583
00584 int numConsumed = b->setDataFromValueVector (vv, currentValueVectorPos);
00585 currentValueVectorPos += numConsumed;
00586
00587 }
00588 }
00589 else {
00590 if (isDynamic == true) {
00591 shared_ptr<DataValue> sizeValue = vv->getValue (currentValueVectorPos++);
00592 int size = ( (Integer*) sizeValue.get())->getValue();
00593
00594
00595
00596 if (itemType.compare ("integer") == 0) {
00597
00598 shared_ptr<IntegerArray> ia = this->addDynamicIntegerArray (itemName);
00599 for (int n = 0; n < size; n++) {
00600 shared_ptr<DataValue> value = vv->getValue (currentValueVectorPos++);
00601 if (value->getType() != INTEGER) {
00602 throw UnexpectedDataTypeException ("DataBox::setDataFromValueVector : unexpected data type");
00603 }
00604 int i = ( (Integer*) value.get())->getValue();
00605 ia->pushBack (i);
00606 }
00607 }
00608 else if (itemType.compare ("double") == 0) {
00609
00610 shared_ptr<DoubleArray> da = this->addDynamicDoubleArray (itemName);
00611 for (int n = 0; n < size; n++) {
00612 shared_ptr<DataValue> value = vv->getValue (currentValueVectorPos++);
00613 if (value->getType() != DOUBLE) {
00614 throw UnexpectedDataTypeException ("DataBox::setDataFromValueVector : unexpected data type");
00615 }
00616 double d = ( (Double*) value.get())->getValue();
00617 da->pushBack (d);
00618 }
00619 }
00620 else if (itemType.compare ("string") == 0) {
00621
00622 shared_ptr<StringArray> sa = this->addDynamicStringArray (itemName);
00623 for (int n = 0; n < size; n++) {
00624 shared_ptr<DataValue> value = vv->getValue (currentValueVectorPos++);
00625 if (value->getType() != STRING) {
00626 throw UnexpectedDataTypeException ("DataBox::setDataFromValueVector : unexpected data type");
00627 }
00628 std::string s = ( (String*) value.get())->getValue();
00629 sa->pushBack (s);
00630 }
00631 }
00632 else {
00633
00634 shared_ptr<DataBoxArray> dba = this->addDynamicDataBoxArray (itemName, itemType);
00635 for (int n = 0; n < size; n++) {
00636 shared_ptr<DataBox> b = DataFactory::buildDataBox (itemType);
00637 int numConsumed = b->setDataFromValueVector (vv, currentValueVectorPos);
00638 currentValueVectorPos += numConsumed;
00639 dba->pushBack (b);
00640 }
00641 }
00642
00643 }
00644 else {
00645 int size = itemDesc->getStaticArraySize();
00646
00647
00648 if (itemType.compare ("integer") == 0) {
00649
00650 shared_ptr<IntegerArray> ia = this->addStaticIntegerArray (itemName, size);
00651 for (int n = 0; n < size; n++) {
00652 shared_ptr<DataValue> value = vv->getValue (currentValueVectorPos++);
00653 if (value->getType() != INTEGER) {
00654 throw UnexpectedDataTypeException ("DataBox::setDataFromValueVector : unexpected data type");
00655 }
00656 (*ia) [n] = static_pointer_cast<Integer> (value);
00657 }
00658 }
00659 else if (itemType.compare ("double") == 0) {
00660
00661 shared_ptr<DoubleArray> da = this->addStaticDoubleArray (itemName, size);
00662 for (int n = 0; n < size; n++) {
00663 shared_ptr<DataValue> value = vv->getValue (currentValueVectorPos++);
00664 if (value->getType() != DOUBLE) {
00665 throw UnexpectedDataTypeException ("DataBox::setDataFromValueVector : unexpected data type");
00666 }
00667 (*da) [n] = static_pointer_cast<Double> (value);
00668 }
00669 }
00670 else if (itemType.compare ("string") == 0) {
00671
00672 shared_ptr<StringArray> sa = this->addStaticStringArray (itemName, size);
00673 for (int n = 0; n < size; n++) {
00674 shared_ptr<DataValue> value = vv->getValue (currentValueVectorPos++);
00675 if (value->getType() != STRING) {
00676 throw UnexpectedDataTypeException ("DataBox::setDataFromValueVector : unexpected data type");
00677 }
00678 (*sa) [n] = static_pointer_cast<String> (value);
00679 }
00680 }
00681 else {
00682
00683
00684 shared_ptr<DataBoxArray> dba = this->addStaticDataBoxArray (itemName, itemType, size);
00685 for (int n = 0; n < size; n++) {
00686 shared_ptr<DataBox> b = (*dba) [n];
00687 int numConsumed = b->setDataFromValueVector (vv, currentValueVectorPos);
00688 currentValueVectorPos += numConsumed;
00689 }
00690 }
00691 }
00692 }
00693 }
00694
00695 return currentValueVectorPos - startPos;
00696 };
00697
00698
00699
00700 DataBox::operator std::string() const
00701 {
00702 std::stringstream ss;
00703 std::map<std::string, shared_ptr<DataValue> >::const_iterator it;
00704 ss << "[DataBox: ";
00705 for (it = nameToPtrMap_.begin(); it != nameToPtrMap_.end(); it++) {
00706 std::pair<std::string, shared_ptr<DataValue> > p = *it;
00707 ss << "(name: " << p.first << "\tvalue:" << static_cast<std::string> (* (p.second)) << ")";
00708 };
00709 ss << "]";
00710 return ss.str();
00711 };
00712
00713
00714
00715 void DataBox::print() const
00716 {
00717 std::cerr << (std::string) *this;
00718 };