XdmfArray.cpp 25.3 KB
Newer Older
Kenneth Leiter's avatar
Kenneth Leiter committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*****************************************************************************/
/*                                    XDMF                                   */
/*                       eXtensible Data Model and Format                    */
/*                                                                           */
/*  Id : XdmfArray.cpp                                                       */
/*                                                                           */
/*  Author:                                                                  */
/*     Kenneth Leiter                                                        */
/*     kenneth.leiter@arl.army.mil                                           */
/*     US Army Research Laboratory                                           */
/*     Aberdeen Proving Ground, MD                                           */
/*                                                                           */
/*     Copyright @ 2011 US Army Research Laboratory                          */
/*     All Rights Reserved                                                   */
/*     See Copyright.txt for details                                         */
/*                                                                           */
/*     This software is distributed WITHOUT ANY WARRANTY; without            */
/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
/*     for more information.                                                 */
/*                                                                           */
/*****************************************************************************/
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
23

24 25
#include <boost/tokenizer.hpp>
#include <sstream>
26
#include <utility>
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
27
#include "XdmfArray.hpp"
28
#include "XdmfArrayType.hpp"
29
#include "XdmfHDF5Controller.hpp"
30
#include "XdmfHeavyDataController.hpp"
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
31
#include "XdmfVisitor.hpp"
32
#include "XdmfError.hpp"
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
33

34 35 36 37 38
XDMF_CHILDREN_IMPLEMENTATION(XdmfArray,
                             XdmfHeavyDataController,
                             HeavyDataController,
                             Name)

39
class XdmfArray::Clear : public boost::static_visitor<void> {
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
40
public:
41

42 43 44 45 46 47 48
  Clear(XdmfArray * const array) :
    mArray(array)
  {
  }

  void
  operator()(const boost::blank & array) const
49
  {
50
    return;
51 52 53 54
  }

  template<typename T>
  void
55
  operator()(const shared_ptr<std::vector<T> > & array) const
56
  {
57
    array->clear();
58
  }
59 60 61 62 63 64 65 66 67 68

  template<typename T>
  void
  operator()(const boost::shared_array<const T> & array) const
  {
    mArray->internalizeArrayPointer();
    boost::apply_visitor(*this,
                         mArray->mArray);
  }

69
private: 
70
  XdmfArray * const mArray;
71 72
};

73
class XdmfArray::Erase : public boost::static_visitor<void> {
74 75
public:

76 77 78
  Erase(XdmfArray * const array,
        const unsigned int index) :
    mArray(array),
79 80 81
    mIndex(index)
  {
  }
82

83 84 85 86 87 88
  void
  operator()(const boost::blank & array) const
  {
    return;
  }

89 90
  template<typename T>
  void
91
  operator()(const shared_ptr<std::vector<T> > & array) const
92 93 94
  {
    array->erase(array->begin() + mIndex);
  }
95

96 97 98 99 100 101 102 103 104
  template<typename T>
  void
  operator()(const boost::shared_array<const T> & array) const
  {
    mArray->internalizeArrayPointer();
    boost::apply_visitor(*this,
                         mArray->mArray);
  }

105 106
private:

107
  XdmfArray * const mArray;
108
  const unsigned int mIndex;
109 110
};

111
class XdmfArray::GetArrayType :
112
  public boost::static_visitor<shared_ptr<const XdmfArrayType> > {
113 114
public:

115 116
  GetArrayType(const shared_ptr<XdmfHeavyDataController> & heavyDataController) :
    mHeavyDataController(heavyDataController)
117 118 119
  {
  }

120
  shared_ptr<const XdmfArrayType>
121 122 123 124 125
  getArrayType(const char * const) const
  {
    return XdmfArrayType::Int8();
  }

126
  shared_ptr<const XdmfArrayType>
127 128 129 130 131
  getArrayType(const short * const) const
  {
    return XdmfArrayType::Int16();
  }

132
  shared_ptr<const XdmfArrayType>
133 134 135 136 137
  getArrayType(const int * const) const
  {
    return XdmfArrayType::Int32();
  }

138
  shared_ptr<const XdmfArrayType>
139 140 141 142 143
  getArrayType(const long * const) const
  {
    return XdmfArrayType::Int64();
  }

144
  shared_ptr<const XdmfArrayType>
145 146 147 148 149
  getArrayType(const float * const) const
  {
    return XdmfArrayType::Float32();
  }

150
  shared_ptr<const XdmfArrayType>
151 152 153 154 155
  getArrayType(const double * const) const
  {
    return XdmfArrayType::Float64();
  }

156
  shared_ptr<const XdmfArrayType>
157 158 159 160 161
  getArrayType(const unsigned char * const) const
  {
    return XdmfArrayType::UInt8();
  }

162
  shared_ptr<const XdmfArrayType>
163 164 165 166 167
  getArrayType(const unsigned short * const) const
  {
    return XdmfArrayType::UInt16();
  }

168
  shared_ptr<const XdmfArrayType>
169 170 171 172 173
  getArrayType(const unsigned int * const) const
  {
    return XdmfArrayType::UInt32();
  }

Kenneth Leiter's avatar
Kenneth Leiter committed
174 175 176 177 178 179
  shared_ptr<const XdmfArrayType>
  getArrayType(const std::string * const) const
  {
    return XdmfArrayType::String();
  }

180 181 182 183 184 185 186 187 188
  shared_ptr<const XdmfArrayType>
  operator()(const boost::blank & array) const
  {
    if(mHeavyDataController) {
      return mHeavyDataController->getType();
    }
    return XdmfArrayType::Uninitialized();
  }

189
  template<typename T>
190 191
  shared_ptr<const XdmfArrayType>
  operator()(const shared_ptr<std::vector<T> > & array) const
192 193 194 195 196
  {
    return this->getArrayType(&(array.get()->operator[](0)));
  }

  template<typename T>
197
  shared_ptr<const XdmfArrayType>
198 199 200 201
  operator()(const boost::shared_array<const T> & array) const
  {
    return this->getArrayType(array.get());
  }
202 203 204 205

private:

  const shared_ptr<XdmfHeavyDataController> mHeavyDataController;
206 207 208 209 210
};

class XdmfArray::GetCapacity : public boost::static_visitor<unsigned int> {
public:

211 212 213
  GetCapacity()
  {
  }
214

215 216 217 218 219 220
  unsigned int
  operator()(const boost::blank & array) const
  {
    return 0;
  }

221 222
  template<typename T>
  unsigned int
223
  operator()(const shared_ptr<std::vector<T> > & array) const
224 225 226
  {
    return array->capacity();
  }
227 228 229 230 231 232 233

  template<typename T>
  unsigned int
  operator()(const boost::shared_array<const T> & array) const
  {
    return 0;
  }
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
234 235
};

236
class XdmfArray::GetValuesPointer :
237
  public boost::static_visitor<const void *> {
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
238 239
public:

240 241 242 243
  GetValuesPointer()
  {
  }

244 245 246 247 248 249
  const void *
  operator()(const boost::blank & array) const
  {
    return NULL;
  }

250
  template<typename T>
251
  const void *
252
  operator()(const shared_ptr<std::vector<T> > & array) const
253 254 255 256 257
  {
    return &array->operator[](0);
  }

  template<typename T>
258
  const void *
259 260 261 262
  operator()(const boost::shared_array<const T> & array) const
  {
    return array.get();
  }
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
263 264
};

265
class XdmfArray::GetValuesString : public boost::static_visitor<std::string> {
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
266 267
public:

268 269 270 271 272
  GetValuesString(const int arrayPointerNumValues) :
    mArrayPointerNumValues(arrayPointerNumValues)
  {
  }

273
  template<typename T, typename U>
274
  std::string
275
  getValuesString(const T * const array,
276 277
                  const int numValues) const
  {
278
    const int lastIndex = numValues - 1;
279 280 281 282 283

    if(lastIndex < 0) {
      return "";
    }

284
    std::stringstream toReturn;
285
    for(int i=0; i<lastIndex; ++i) {
286
      toReturn << (U)array[i] << " ";
287
    }
288
    toReturn << (U)array[lastIndex];
289 290 291
    return toReturn.str();
  }

292 293 294 295 296 297 298
  std::string
  getValuesString(const char * const array,
                  const int numValues) const
  {
    return getValuesString<char, int>(array, numValues);
  }

299 300 301 302
  std::string
  getValuesString(const unsigned char * const array,
                  const int numValues) const
  {
303
    return getValuesString<unsigned char, int>(array, numValues);
304 305 306 307 308 309 310
  }

  template<typename T>
  std::string
  getValuesString(const T * const array,
                  const int numValues) const
  {
311
    return getValuesString<T, T>(array, numValues);
312 313
  }

314 315 316 317 318 319
  std::string
  operator()(const boost::blank & array) const
  {
    return "";
  }

320 321
  template<typename T>
  std::string
322
  operator()(const shared_ptr<std::vector<T> > & array) const
323 324 325 326 327 328 329 330 331 332
  {
    return getValuesString(&(array->operator[](0)), array->size());
  }

  template<typename T>
  std::string
  operator()(const boost::shared_array<const T> & array) const
  {
    return getValuesString(array.get(), mArrayPointerNumValues);
  }
333 334 335

private:

336
  const unsigned int mArrayPointerNumValues;
337 338
};

339 340 341
class XdmfArray::InsertArray : public boost::static_visitor<void> {
public:

342 343
  InsertArray(XdmfArray * const array,
              const unsigned int startIndex,
344 345 346
              const unsigned int valuesStartIndex,
              const unsigned int numValues,
              const unsigned int arrayStride,
347
              const unsigned int valuesStride,
348 349 350
              std::vector<unsigned int> & dimensions,
              const shared_ptr<const XdmfArray> & arrayToCopy) :
    mArray(array),
351 352 353 354
    mStartIndex(startIndex),
    mValuesStartIndex(valuesStartIndex),
    mNumValues(numValues),
    mArrayStride(arrayStride),
355
    mValuesStride(valuesStride),
356 357
    mDimensions(dimensions),
    mArrayToCopy(arrayToCopy)
358 359 360 361
  {
  }

  void
362 363 364 365 366 367 368 369 370 371
  operator()(const boost::blank & array) const
  {
    mArray->initialize(mArrayToCopy->getArrayType());
    boost::apply_visitor(*this,
                         mArray->mArray);
  }

  template<typename T>
  void
  operator()(const shared_ptr<std::vector<T> > & array) const
372 373 374 375 376 377 378
  {
    unsigned int size = mStartIndex + mNumValues;
    if(mArrayStride > 1) {
      size = mStartIndex + mNumValues * mArrayStride - 1;
    }
    if(array->size() < size) {
      array->resize(size);
379
      mDimensions.clear();
380
    }
381 382 383 384 385 386 387 388 389 390 391 392 393 394
    mArrayToCopy->getValues(mValuesStartIndex,
                            &(array->operator[](mStartIndex)),
                            mNumValues,
                            mValuesStride,
                            mArrayStride);
  }

  template<typename T>
  void
  operator()(const boost::shared_array<const T> & array) const
  {
    mArray->internalizeArrayPointer();
    boost::apply_visitor(*this,
                         mArray->mArray);
395
  }
396 397 398

private:

399
  XdmfArray * const mArray;
400 401 402 403 404
  const unsigned int mStartIndex;
  const unsigned int mValuesStartIndex;
  const unsigned int mNumValues;
  const unsigned int mArrayStride;
  const unsigned int mValuesStride;
405
  std::vector<unsigned int> & mDimensions;
406
  const shared_ptr<const XdmfArray> mArrayToCopy;
407 408
};

409
class XdmfArray::InternalizeArrayPointer : public boost::static_visitor<void> {
410 411
public:

412 413 414 415 416
  InternalizeArrayPointer(XdmfArray * const array) :
    mArray(array)
  {
  }

417 418 419 420 421 422 423 424 425 426 427 428 429
  void
  operator()(const boost::blank & array) const
  {
    return;
  }

  template<typename T>
  void
  operator()(const shared_ptr<std::vector<T> > & array) const
  {
    return;
  }

430 431 432 433
  template<typename T>
  void
  operator()(const boost::shared_array<const T> & array) const
  {
434 435 436 437
    const T * const pointer = array.get();
    shared_ptr<std::vector<T> > newArray(new std::vector<T>(pointer,
                                                            pointer + mArray->mArrayPointerNumValues));
    mArray->mArray = newArray;
438 439
    mArray->mArrayPointerNumValues = 0;
  }
440 441 442

private:

443
  XdmfArray * const mArray;
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
444 445
};

446
class XdmfArray::Reserve : public boost::static_visitor<void> {
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
447 448
public:

449 450 451 452
  Reserve(XdmfArray * const array,
          const unsigned int size):
    mArray(array),
    mSize(size)
453 454 455 456
  {
  }

  void
457
  operator()(const boost::blank & array) const
458
  {
459
    mArray->mTmpReserveSize = mSize;
460
  }
461

462 463 464
  template<typename T>
  void
  operator()(shared_ptr<std::vector<T> > & array) const
465
  {
466
    array->reserve(mSize);
467
  }
468

469 470
  template<typename T>
  void
471
  operator()(const boost::shared_array<const T> & array) const
472
  {
473 474 475
    mArray->internalizeArrayPointer();
    boost::apply_visitor(*this,
                         mArray->mArray);
476
  }
477 478 479

private:

480
  XdmfArray * const mArray;
481
  const unsigned int mSize;
482 483
};

484 485 486
class XdmfArray::Size : public boost::static_visitor<unsigned int> {
public:

487 488 489 490 491 492 493
  Size(const XdmfArray * const array) :
    mArray(array)
  {
  }

  unsigned int
  operator()(const boost::blank & array) const
494
  {
495 496
    if(mArray->mHeavyDataControllers.size()>0) {
      return mArray->mHeavyDataControllers[0]->getSize();//modify this to compile all controllers
497 498
    }
    return 0;
499
  }
500

501 502
  template<typename T>
  unsigned int
503
  operator()(const shared_ptr<std::vector<T> > & array) const
504 505 506
  {
    return array->size();
  }
507 508 509 510 511 512 513 514 515 516 517

  template<typename T>
  unsigned int
  operator()(const boost::shared_array<const T> & array) const
  {
    return mArray->mArrayPointerNumValues;
  }

private:

  const XdmfArray * const mArray; 
518 519
};

520
shared_ptr<XdmfArray>
521
XdmfArray::New()
522
{
523
  shared_ptr<XdmfArray> p(new XdmfArray());
524
  return p;
525 526
}

Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
527
XdmfArray::XdmfArray() :
528 529 530
  mArrayPointerNumValues(0),
  mName(""),
  mTmpReserveSize(0)
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
531 532 533 534 535 536 537
{
}

XdmfArray::~XdmfArray()
{
}

538
const std::string XdmfArray::ItemTag = "DataItem";
539

540 541
void
XdmfArray::clear()
542
{
543 544 545
  boost::apply_visitor(Clear(this), 
                       mArray);
  mDimensions.clear();
546 547
}

548 549
void
XdmfArray::erase(const unsigned int index)
550
{
551 552 553 554
  boost::apply_visitor(Erase(this,
                             index),
                       mArray);
  mDimensions.clear();
555 556
}

557
shared_ptr<const XdmfArrayType>
558
XdmfArray::getArrayType() const
559
{
560 561 562 563 564 565 566 567 568 569
  if (mHeavyDataControllers.size()>0)
  {
    return boost::apply_visitor(GetArrayType(mHeavyDataControllers[0]), 
                                mArray);
  }
  else
  {
    return boost::apply_visitor(GetArrayType(shared_ptr<XdmfHDF5Controller>()),
                                mArray);
  }
570 571
}

572 573
unsigned int
XdmfArray::getCapacity() const
574
{
575 576
  return boost::apply_visitor(GetCapacity(), 
                              mArray);
577 578
}

579 580 581
std::vector<unsigned int>
XdmfArray::getDimensions() const
{
582
  if(mDimensions.size() == 0) {
583 584 585 586 587 588 589 590 591 592 593
    if(!this->isInitialized() && mHeavyDataControllers.size() > 0) {
      std::vector<unsigned int> returnDimensions;
      std::vector<unsigned int> tempDimensions;
      for (int i = 0; i < mHeavyDataControllers.size(); i++) {
        tempDimensions = mHeavyDataControllers[i]->getDimensions();
        for (int j =0; i < tempDimensions.size(); i++)
        {
          returnDimensions.push_back(tempDimensions[i]);
        }
      }
      return returnDimensions;
594
    }
595 596
    const unsigned int size = this->getSize();
    return std::vector<unsigned int>(1, size);
597
  }
598
  return mDimensions;
599 600
}

601
std::string
602
XdmfArray::getDimensionsString() const
603
{
604
  const std::vector<unsigned int> dimensions = this->getDimensions();
605 606
  return GetValuesString(dimensions.size()).getValuesString(&dimensions[0],
                                                            dimensions.size());
607 608
}

609 610
std::map<std::string, std::string>
XdmfArray::getItemProperties() const
611
{
612
  std::map<std::string, std::string> arrayProperties;
613
  if(mHeavyDataControllers.size()>0) {
614
    arrayProperties.insert(std::make_pair("Format",
615
                                          mHeavyDataControllers[0]->getName()));
616 617
  }
  else {
618
    arrayProperties.insert(std::make_pair("Format", "XML"));
619
  }
620 621
  arrayProperties.insert(std::make_pair("Dimensions", 
                                        this->getDimensionsString()));
622
  if(mName.compare("") != 0) {
623
    arrayProperties.insert(std::make_pair("Name", mName));
624
  }
625
  shared_ptr<const XdmfArrayType> type = this->getArrayType();
626 627
  type->getProperties(arrayProperties);
  return arrayProperties;
628 629
}

630 631
std::string
XdmfArray::getItemTag() const
632
{
633
  return ItemTag;
634 635
}

636 637
std::string
XdmfArray::getName() const
638
{
639
  return mName;
640 641
}

642 643
unsigned int
XdmfArray::getSize() const
644
{
645 646
  return boost::apply_visitor(Size(this), 
                              mArray);
647 648
}

649 650
void *
XdmfArray::getValuesInternal()
651
{
652 653
  return const_cast<void *>
    (static_cast<const XdmfArray &>(*this).getValuesInternal());
654 655
}

656 657
const void *
XdmfArray::getValuesInternal() const
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
658
{
659 660
  return boost::apply_visitor(GetValuesPointer(), 
                              mArray);
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
661 662
}

663 664
std::string
XdmfArray::getValuesString() const
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
665
{
666 667
  return boost::apply_visitor(GetValuesString(mArrayPointerNumValues), 
                              mArray);
668 669
}

670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696
shared_ptr<XdmfHeavyDataController>
XdmfArray::getHeavyDataController()
{
  return boost::const_pointer_cast<XdmfHeavyDataController>
    (static_cast<const XdmfArray &>(*this).getHeavyDataController(0));
}

shared_ptr<const XdmfHeavyDataController>
XdmfArray::getHeavyDataController() const
{
  if (mHeavyDataControllers.size()>0) {
    return mHeavyDataControllers[0];
  }
  else {
    return shared_ptr<XdmfHeavyDataController>();
  }
}

void
XdmfArray::setHeavyDataController(shared_ptr<XdmfHeavyDataController> newController)
{
  //since this is replacing the previous version which was designed to completely replace the controller of the array
  //it will clear the current controllers before adding the new one in
  mHeavyDataControllers.clear();
  mHeavyDataControllers.push_back(newController);
}

697
void
698
XdmfArray::initialize(const shared_ptr<const XdmfArrayType> arrayType,
699
                      const unsigned int size)
700
{
701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727
  if(arrayType == XdmfArrayType::Int8()) {
    this->initialize<char>(size);
  }
  else if(arrayType == XdmfArrayType::Int16()) {
    this->initialize<short>(size);
  }
  else if(arrayType == XdmfArrayType::Int32()) {
    this->initialize<int>(size);
  }
  else if(arrayType == XdmfArrayType::Int64()) {
    this->initialize<long>(size);
  }
  else if(arrayType == XdmfArrayType::Float32()) {
    this->initialize<float>(size);
  }
  else if(arrayType == XdmfArrayType::Float64()) {
    this->initialize<double>(size);
  }
  else if(arrayType == XdmfArrayType::UInt8()) {
    this->initialize<unsigned char>(size);
  }
  else if(arrayType == XdmfArrayType::UInt16()) {
    this->initialize<unsigned short>(size);
  }
  else if(arrayType == XdmfArrayType::UInt32()) {
    this->initialize<unsigned int>(size);
  }
Kenneth Leiter's avatar
Kenneth Leiter committed
728 729 730
  else if(arrayType == XdmfArrayType::String()) {
    this->initialize<std::string>(size);
  }
731 732 733 734
  else if(arrayType == XdmfArrayType::Uninitialized()) {
    this->release();
  }
  else {
735 736
    XdmfError::message(XdmfError::FATAL, 
                       "Array of unsupported type in XdmfArray::initialize");
737
  }
738 739
}

740
void
741
XdmfArray::initialize(const shared_ptr<const XdmfArrayType> arrayType,
742 743 744
                      const std::vector<unsigned int> & dimensions)
{
  mDimensions = dimensions;
745 746
  const unsigned int size = std::accumulate(dimensions.begin(),
                                            dimensions.end(),
747 748 749 750 751
                                            1,
                                            std::multiplies<unsigned int>());
  return this->initialize(arrayType, size);
}

752 753
void
XdmfArray::insert(const unsigned int startIndex,
754
                  const shared_ptr<const XdmfArray> values,
755 756 757 758
                  const unsigned int valuesStartIndex,
                  const unsigned int numValues,
                  const unsigned int arrayStride,
                  const unsigned int valuesStride)
759
{
760 761
  boost::apply_visitor(InsertArray(this,
                                   startIndex,
762 763 764
                                   valuesStartIndex,
                                   numValues,
                                   arrayStride,
765
                                   valuesStride,
766 767 768
                                   mDimensions,
                                   values),
                       mArray);
769 770
}

771 772
bool
XdmfArray::isInitialized() const
773
{
774 775 776 777 778 779 780
  try {
    boost::get<boost::blank>(mArray);
    return false;
  }
  catch(const boost::bad_get & exception) {
  }
  return true;
781 782
}

783 784
void
XdmfArray::internalizeArrayPointer()
785
{
786 787
  boost::apply_visitor(InternalizeArrayPointer(this), 
                       mArray);
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
788 789
}

790 791
void
XdmfArray::populateItem(const std::map<std::string, std::string> & itemProperties,
792
                        const std::vector<shared_ptr<XdmfItem> > & childItems,
793
                        const XdmfCoreReader * const reader)
794
{
795
  //This inserts any XdmfInformation in childItems into the object.
796 797
  XdmfItem::populateItem(itemProperties, childItems, reader);

798
  const shared_ptr<const XdmfArrayType> arrayType = 
799 800 801
    XdmfArrayType::New(itemProperties);

  std::map<std::string, std::string>::const_iterator content =
802
    itemProperties.find("Content0");
803
  if(content == itemProperties.end()) {
804 805 806
    XdmfError::message(XdmfError::FATAL, 
                       "'Content' not found in itemProperties in "
                       "XdmfArray::populateItem");
807
  }
808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829

  //this was originally a constant, but the compiler doesn't like creating vectors of constant strings.
  std::vector<std::string> contentVals;
  contentVals.push_back(content->second);

  int contentIndex=1;

  bool endOfContent = false;

  while(!endOfContent)
  {
    std::stringstream contentSearch;
    contentSearch << "Content" << contentIndex;
    content = itemProperties.find(contentSearch.str());
    if(content != itemProperties.end()) {
      contentVals.push_back(content->second);
    }
    else {
      endOfContent = true;
    }
    contentIndex++;
  }
830

831
  std::map<std::string, std::string>::const_iterator dimensions =
832
    itemProperties.find("Dimensions");
833
  if(dimensions == itemProperties.end()) {
834 835 836
    XdmfError::message(XdmfError::FATAL, 
                       "'Dimensions' not found in itemProperties in "
                       "XdmfArray::populateItem");
837
  }
838 839 840 841 842 843 844
   
  boost::tokenizer<> tokens(dimensions->second);
  for(boost::tokenizer<>::const_iterator iter = tokens.begin();
      iter != tokens.end();
      ++iter) {
    mDimensions.push_back(atoi((*iter).c_str()));
  }
845 846 847

  std::map<std::string, std::string>::const_iterator format =
    itemProperties.find("Format");
848 849 850 851 852 853 854
  if(format == itemProperties.end()) {
    XdmfError::message(XdmfError::FATAL, 
                       "'Format' not found in itemProperties in "
                       "XdmfArray::populateItem");
  }
  const std::string & formatVal = format->second;

855

856
  if(formatVal.compare("HDF") == 0) {
857 858 859 860 861
    contentIndex = 0;
    int contentStep = 2;
    while (contentIndex < contentVals.size()) {
      size_t colonLocation = contentVals[contentIndex].find(":");
      if(colonLocation == std::string::npos) {
862
        XdmfError::message(XdmfError::FATAL, 
863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888
                           "':' not found in content in "
                           "XdmfArray::populateItem -- double check an HDF5 "
                           "data set is specified for the file");
      }

      std::string hdf5Path = contentVals[contentIndex].substr(0, colonLocation);
      std::string dataSetPath = contentVals[contentIndex].substr(colonLocation+1);

      //parse dimensions from the content
      std::vector<unsigned int> contentDims;
      try {
        //this is the string that contains the dimensions
        boost::tokenizer<> dimtokens(contentVals[contentIndex+1]);
        for(boost::tokenizer<>::const_iterator iter = dimtokens.begin();
            iter != dimtokens.end();
            ++iter) {
          contentDims.push_back(atoi((*iter).c_str()));
        }
	contentStep = 2;//if this works then the dimension content should be skipped over
      }
      catch (...) {//if it fails then it means that the next content is not a dimension string
        //in this case it is assumed that the controller will have dimensions equal to the array
        for (int j = 0; j < mDimensions.size(); j++) {
          contentDims.push_back(mDimensions[j]);
        }
        contentStep = 1;
889
      }
890

891 892 893 894 895 896 897 898 899 900 901 902
      mHeavyDataControllers.push_back( 
        XdmfHDF5Controller::New(hdf5Path,
                                dataSetPath,
                                arrayType,
                                std::vector<unsigned int>(contentDims.size(),
                                                          0),
                                std::vector<unsigned int>(contentDims.size(),
                                                          1),
                                contentDims,
                                contentDims)
      );
      contentIndex+=contentStep;
903
    }
904 905 906 907 908 909
  }
  else if(formatVal.compare("XML") == 0) {
    this->initialize(arrayType,
                     mDimensions);
    unsigned int index = 0;
    boost::char_separator<char> sep(" \t\n");
910
    boost::tokenizer<boost::char_separator<char> > tokens(contentVals[0], sep);
Kenneth Leiter's avatar
Kenneth Leiter committed
911 912 913 914 915 916 917 918 919 920 921 922 923 924 925
    if(arrayType == XdmfArrayType::String()) {
      for(boost::tokenizer<boost::char_separator<char> >::const_iterator
            iter = tokens.begin();
          iter != tokens.end();
          ++iter, ++index) {
        this->insert(index, *iter);
      }
    }
    else {
      for(boost::tokenizer<boost::char_separator<char> >::const_iterator
            iter = tokens.begin();
          iter != tokens.end();
          ++iter, ++index) {
        this->insert(index, atof((*iter).c_str()));
      }
926 927 928
    }
  }
  else {
929
    XdmfError::message(XdmfError::FATAL, 
930 931
                       "Neither 'HDF' nor 'XML' specified as 'Format' "
                       "in XdmfArray::populateItem");
932 933 934 935 936 937 938 939 940 941
  }

  std::map<std::string, std::string>::const_iterator name =
    itemProperties.find("Name");
  if(name != itemProperties.end()) {
    mName = name->second;
  }
  else {
    mName = "";
  }
942 943
}

944 945
void
XdmfArray::read()
946
{
947 948 949 950 951 952 953 954
  if(mHeavyDataControllers.size() > 0) {
    mHeavyDataControllers[0]->read(this);
    for (int i = 1; i < mHeavyDataControllers.size(); i++)
    {
      shared_ptr<XdmfArray> tempArray = XdmfArray::New();
      mHeavyDataControllers[i]->read(tempArray.get());
      this->insert(this->getSize(), tempArray, 0, tempArray->getSize());
    }
955
  }
956 957
}

958 959
void
XdmfArray::release()
960
{
961 962
  mArray = boost::blank();
  mArrayPointerNumValues = 0;
963
  mDimensions.clear();
964 965
}

966 967
void
XdmfArray::reserve(const unsigned int size)
968
{
969 970 971
  boost::apply_visitor(Reserve(this,
                               size),
                       mArray);
972 973
}

974 975
void
XdmfArray::setName(const std::string & name)
976
{
977
  mName = name;
978 979
}

980
void
981
XdmfArray::swap(const shared_ptr<XdmfArray> array)
982
{
983 984 985
  std::swap(mArray, array->mArray);
  std::swap(mArrayPointerNumValues, array->mArrayPointerNumValues);
  std::swap(mDimensions, array->mDimensions);
986
  std::swap(mHeavyDataControllers, array->mHeavyDataControllers);
987
}