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
00031
00032
00033 #ifndef __RVL_TOOLS_NEW_CONTENT_PACKAGE_
00034 #define __RVL_TOOLS_NEW_CONTENT_PACKAGE_
00035
00036 #include "local.hh"
00037 #include "dejavu.hh"
00038
00039 namespace RVL {
00040
00041
00042 template<typename T, typename M>
00043 class ContentPackage;
00044
00045
00046
00047
00055 template<typename MetaType>
00056 size_t getDataSize(MetaType const & md) {
00057 size_t t = md;
00058 return t;
00059 }
00060
00066 template<class MetaType>
00067 size_t getMetaSize(MetaType const & md) {
00068 return sizeof(MetaType);
00069 }
00070
00073 template<typename MetaType>
00074 char * serialize(MetaType const & mt, size_t & len) {
00075 len = getMetaSize<MetaType>(mt);
00076 char * cbuf = new char[len];
00077 memcpy(cbuf, (char *)(&mt), len);
00078 return cbuf;
00079 }
00080
00084 template<typename MetaType>
00085 MetaType * deserialize(char * cbuf, size_t len) {
00086
00087
00088 MetaType * mt = new MetaType;
00089 if (len < getMetaSize<MetaType>(*mt)) {
00090 RVLException e;
00091 e<<"ERROR: deserialize[ContentPackage MetaType]\n";
00092 e<<" asserted size of char buf too small to hold\n";
00093 e<<" metadata object of this type\n";
00094 throw e;
00095 }
00096 memcpy((char *)mt,cbuf,getMetaSize<MetaType>(*mt));
00097 return mt;
00098 }
00099
00103 template<typename DataType, typename MetaType>
00104 char * serialize(ContentPackage<DataType,MetaType> const & cp, size_t & len) {
00105 size_t mlen = 0;
00106 char * mbuf = serialize<MetaType>(cp.getMetadata(), mlen);
00107 size_t dlen = getDataSize<MetaType>(cp.getMetadata())*sizeof(DataType);
00108 len = mlen + dlen;
00109 char * cbuf = new char[len];
00110 memcpy(cbuf,mbuf,mlen);
00111 memcpy(&(cbuf[mlen]),(char *)(cp.getData()),dlen);
00112 delete [] mbuf;
00113 return cbuf;
00114 }
00115
00119 template<typename DataType, typename MetaType>
00120 ContentPackage<DataType,MetaType> * deserialize(char * cbuf, size_t len) {
00121 try {
00122 MetaType * mt = deserialize<MetaType>(cbuf,len);
00123 int clen = getMetaSize<MetaType>(*mt) + getDataSize<MetaType>(*mt)*sizeof(DataType);
00124 if (len != clen) {
00125 RVLException e;
00126 e<<"ERROR: deserialize[ContentPackage]\n";
00127 e<<" asserted size of char buffer appears to differ from that needed\n";
00128 e<<" to store CP object of given type\n";
00129 e<<" asserted size of char buffer = "<<len<<"\n";
00130 e<<" require buffer size for CP = "<<clen<<"\n";
00131 throw e;
00132 }
00133 ContentPackage<DataType,MetaType> * cp = new ContentPackage<DataType,MetaType>;
00134 cp->initialize(*mt);
00135 delete mt;
00136 memcpy((char *)(cp->getData()), &(cbuf[getMetaSize<MetaType>(*mt)]),getDataSize<MetaType>(*mt)*sizeof(DataType) );
00137 return cp;
00138 }
00139 catch (RVLException & e) {
00140 e<<"\ncalled from deserialize[ContentPackage]\n";
00141 throw e;
00142 }
00143 }
00144
00147 template<class MetaType>
00148 ostream & writeMeta(MetaType const & md, ostream & e) {
00149 e<<md<<"\n"; return e; }
00150
00153 template<typename DataType,typename MetaType>
00154 DataType * newData(MetaType & md) {
00155 return new DataType[getDataSize<MetaType>(md)];
00156 }
00157
00160 template<typename DataType,typename MetaType>
00161 void deleteData(DataType ** d, MetaType ** md) {
00162 delete [] *d; *d=NULL;
00163 }
00164
00201 template<class DataType, class MetaType >
00202 class ContentPackage: public LocalDataContainer<DataType> {
00203
00204 private:
00205
00206 mutable MetaType * md;
00207 mutable DataType * d;
00208 bool own;
00209
00210 public:
00211
00214 ContentPackage(const ContentPackage<DataType,MetaType> & bin)
00215 : md(NULL), d(NULL), own(bin.own) {
00216 if (bin.md) {
00217 md = new MetaType(*(bin.md));
00218 if (own) {
00219
00220 d=newData<DataType,MetaType>(*md);
00221 memcpy(d,bin.d,getDataSize<MetaType>(*md)*sizeof(DataType));
00222 }
00223 else {
00224 d = bin.d;
00225 }
00226 }
00227
00228
00229
00230 }
00231
00233 ContentPackage()
00234 :md(NULL), d(NULL), own(true) {
00235
00236 }
00237
00238 virtual ~ContentPackage() {
00239
00240
00241
00242 if (d && own) deleteData<DataType,MetaType>(&d,&md);
00243
00244
00245
00246 if (md) {
00247
00248 delete md; md = NULL;
00249
00250 }
00251
00252 }
00253
00258 bool initialize(MetaType const & _md,
00259 LocalDataContainer<DataType> * p = NULL,
00260 size_t start = 0) {
00261 if (md) return false;
00262 md = new MetaType(_md);
00263
00264
00265
00266 if (p) {
00267 if (getDataSize<MetaType>(*md) <= p->getSize()-start) {
00268 d = &((p->getData())[start]);
00269 own = false;
00270 return true;
00271 }
00272 else {
00273
00274
00275
00276
00277 delete md;
00278 md=NULL;
00279 return false;
00280 }
00281 }
00282 else {
00283
00284 d=newData<DataType,MetaType>(*md);
00285 return true;
00286 }
00287 }
00288
00290 bool isInitialized() const { if (md) return true; return false; }
00291
00293 ContentPackage<DataType,MetaType> &
00294 operator=(ContentPackage<DataType,MetaType> const & src) {
00295 if (this != &src) {
00296 if (*md != *(src.md)) {
00297 RVLException e;
00298 e<<"Error: ContentPackage assignment op\n";
00299 e<<"metadata of this differs from metadata of source\n";
00300 throw e;
00301 }
00302 size_t n = getDataSize<MetaType>(*md);
00303 if (!d) d = new DataType[n];
00304 memcpy(d,src.d,n*sizeof(DataType));
00305 }
00306 return *this;
00307 }
00309 bool operator==(ContentPackage<DataType,MetaType> const & a) const {
00310 if (this == &a) return true;
00311 if (*md != *(a.md)) return false;
00312 if (getSize() != a.getSize()) return false;
00313 for (size_t i=0;i<getSize();i++) {
00314 if (getData()[i] != a.getData()[i]) return false;
00315 }
00316 return true;
00317 }
00318 bool operator!=(ContentPackage<DataType,MetaType> const & a) const {
00319 return !operator==(a);
00320 }
00321
00322 bool isCompatible(ContentPackage<DataType,MetaType> const & a) const {
00323 return (this->getMetadata() == a.getMetadata());
00324 }
00325
00327 MetaType & getMetadata() {
00328 if (!md) {
00329 RVLException e;
00330 e<<"Error: ContentPackage::getMetaData\n";
00331 e<<"metadata not initialized yet\n";
00332 throw e;
00333 }
00334 return *md;
00335 }
00336
00338 MetaType const & getMetadata() const {
00339 if (!md) {
00340 RVLException e;
00341 e<<"Error: ContentPackage::getMetaData\n";
00342 e<<"metadata not initialized yet\n";
00343 throw e;
00344 }
00345 return *md;
00346 }
00347
00349 size_t getSize() const {
00350 if (md) return getDataSize<MetaType>(*md);
00351 return 0;
00352 }
00353
00355 DataType * getData() {
00356 if (!d) {
00357 RVLException e;
00358 e<<"Error: ContentPackage::getData\n";
00359 e<<"data not initialized yet\n";
00360 throw e;
00361 }
00362 return d;
00363 }
00365 DataType const * getData() const {
00366 if (!d) {
00367 RVLException e;
00368 e<<"Error: ContentPackage::getData\n";
00369 e<<"data not initialized yet\n";
00370 throw e;
00371 }
00372 return d;
00373 }
00374
00375 ostream & write(ostream & str) const {
00376 str<<"ContentPackage LDC, MetaData = \n";
00377 if (md) {
00378 writeMeta<MetaType>(*md,str);
00379 }
00380 else {
00381 str<<"(not initialized)\n";
00382 }
00383 str<<" and data array\n";
00384 for (size_t i=0;i<this->getSize(); i++) {
00385 str<<" "<<i<<". ";
00386 writeMeta<DataType>(d[i],str);
00387 }
00388 return str;
00389 }
00390 };
00391
00392
00396 template<typename Source, typename Target>
00397 void copyCP(Source const & in, Target & out) {
00398 try {
00399 size_t n = min(in.getSize(),out.getSize());
00400 for (size_t i=0;i<n;i++) out.getData()[i]=in.getData()[i];
00401 }
00402 catch (RVLException & e) {
00403 e<<"\ncalled from copyCP\n";
00404 throw e;
00405 }
00406 }
00407
00458 template<typename DataType, typename MetaType>
00459 class PackageContainer:
00460 public DataContainer {
00461
00462 protected:
00463
00483 virtual ContentPackage<DataType,MetaType>
00484 & get(bool & more) = 0;
00485 virtual ContentPackage<DataType,MetaType> const
00486 & get(bool & more) const = 0;
00487
00492 virtual void put() const = 0;
00493
00496 virtual void reset() const = 0;
00497
00498 public:
00499
00500 PackageContainer() {}
00501 PackageContainer(PackageContainer<DataType,MetaType> const &) {}
00502 virtual ~PackageContainer() {}
00503
00505 virtual void eval(FunctionObject & f,
00506 std::vector<DataContainer const *> & x) {
00507 try {
00508
00509
00510 this->reset();
00511
00512
00513 std::vector<PackageContainer<DataType,MetaType> const *> pcx(x.size());
00514 for (size_t i=0;i<x.size();i++) {
00515 if (!(pcx[i] = dynamic_cast<PackageContainer<DataType,MetaType>
00516 const *>(x[i]))) {
00517 RVLException e;
00518 e<<"Error: PackageContainer::eval(FO)\n";
00519 e<<"at least one other arg is not a package container.\n";
00520 for (size_t j=0;j<x.size();j++) {
00521 e<<"*** arg "<<j<<":\n";
00522 x[j]->write(e);
00523 }
00524 throw e;
00525 }
00526
00527 if (this == pcx[i]) {
00528 RVLException e;
00529 e<<"Error: PackageContainer::eval(FO)\n";
00530 e<<"input argument "<<i<<" aliased with output\n";
00531 throw e;
00532 }
00533 pcx[i]->reset();
00534 }
00535
00536 bool more = true;
00537 std::vector<DataContainer const *> cpx(x.size());
00538
00539
00540
00541 while (more) {
00542 for (size_t i=0;i<x.size();i++) {
00543
00544 size_t j=i;
00545 dejavu<PackageContainer<DataType,MetaType> const>(&j,pcx);
00546
00547 if (j==i) { cpx[i]=&(pcx[i]->get(more)); }
00548
00549 else { cpx[i] = cpx[j]; }
00550 }
00551
00552
00553 ContentPackage<DataType,MetaType> & cp = this->get(more);
00554
00555 cp.eval(f,cpx);
00556
00557 this->put();
00558 }
00559 }
00560 catch (RVLException & e) {
00561 e<<"\ncalled from PackageContainer::eval(FO)\n";
00562 throw e;
00563 }
00564 }
00565
00567 virtual void eval(FunctionObjectConstEval & f,
00568 vector<DataContainer const *> & x) const {
00569 try {
00570 this->reset();
00571 std::vector<PackageContainer<DataType,MetaType> const *> pcx(x.size());
00572 for (size_t i=0;i<x.size();i++) {
00573 if (!(pcx[i] =
00574 dynamic_cast<PackageContainer<DataType,MetaType>
00575 const *>(x[i]))) {
00576 RVLException e;
00577 e<<"Error: PackageContainer::eval(FOR)\n";
00578 e<<"at least one other arg is not a package container.\n";
00579 throw e;
00580 }
00581 pcx[i]->reset();
00582 }
00583 bool more = true;
00584 std::vector<DataContainer const *> cpx(x.size());
00585
00586 while (more) {
00587 ContentPackage<DataType,MetaType> const & cp = this->get(more);
00588 for (size_t i=0;i<x.size();i++) {
00589
00590 if (this == pcx[i]) {
00591 cpx[i] = &cp;
00592 }
00593 else {
00594
00595 size_t j=i;
00596 dejavu<PackageContainer<DataType,MetaType> const>(&j,pcx);
00597
00598 if (j==i) {
00599 cpx[i]=&(pcx[i]->get(more)); }
00600
00601 else {
00602 cpx[i] = cpx[j];
00603 }
00604 }
00605 }
00606 cp.eval(f,cpx);
00607 }
00608 }
00609 catch (RVLException & e) {
00610 e<<"\ncalled from PackageContainer::eval(FOR)\n";
00611 throw e;
00612 }
00613 }
00614
00615 };
00616
00626 template<typename DataType,typename MetaType>
00627 class PackageContainerFactory: public DataContainerFactory {
00628 protected:
00629
00630 virtual PackageContainer<DataType,MetaType> * buildPC() const = 0;
00631
00632 public:
00633
00635 virtual PackageContainerFactory<DataType,MetaType> * clone() const = 0;
00636
00637 DataContainer * build() const { return buildPC(); }
00638
00639 virtual bool compare( DataContainerFactory const & dcf) const {
00640 PackageContainerFactory<DataType,MetaType> const * ptr = NULL;
00641 if ((ptr =
00642 dynamic_cast< PackageContainerFactory<DataType,MetaType> const * >(&dcf)))
00643 return true;
00644 return false;
00645 }
00646
00647 virtual bool isCompatible(DataContainer const & dc) const {
00648 PackageContainer<DataType,MetaType> const * ptr = NULL;
00649 if ((ptr =
00650 dynamic_cast< PackageContainer<DataType,MetaType> const * >(&dc)))
00651 return true;
00652 return false;
00653 }
00654
00655 virtual ostream & write(ostream & str) const {
00656 str<<"PackageContainerFactory\n";
00657 return str;
00658 }
00659 };
00660
00669 template<typename Datatype, typename Metatype>
00670 class SingleDataContainer: public PackageContainer<Datatype,Metatype> {
00671
00672 private:
00673
00674 ContentPackage<Datatype,Metatype> gd;
00675 mutable int nrep;
00676 int nrep0;
00677
00678 protected:
00679
00680 ContentPackage<Datatype,Metatype> & get(bool & more) {
00681 nrep--;
00682 if (nrep<1) more = false;
00683 return gd;
00684 }
00685
00686 ContentPackage<Datatype,Metatype> const & get(bool & more) const {
00687 nrep--;
00688 if (nrep<1) more = false;
00689 return gd;
00690 }
00691
00692 void put() const {}
00693
00694 void reset() const { nrep=nrep0; }
00695
00696 public:
00697
00698 SingleDataContainer(int _nrep = 1)
00699 : PackageContainer<Datatype,Metatype>(),
00700 gd(), nrep(_nrep), nrep0(nrep) {}
00701
00702 SingleDataContainer(SingleDataContainer<Datatype,Metatype> const & g)
00703 : PackageContainer<Datatype,Metatype>(g), gd(g.gd),
00704 nrep(g.nrep), nrep0(g.nrep0) {}
00705 ~SingleDataContainer() {}
00706
00707 void initialize(Metatype const & g) { gd.initialize(g); }
00708 Metatype const & getMetadata() const {
00709 if (gd.isInitialized()) return gd.getMetadata();
00710 RVLException e;
00711 e<<"Error: SingleDataContainer::getMetadata\n";
00712 e<<"cannot return reference to internal Metadata, as\n";
00713 e<<"this is not initialized yet.\n";
00714 throw e;
00715 }
00716
00717 ostream & write(ostream & e) const {
00718 e<<"SingleDataContainer encapsulating ContentPackage object:\n";
00719 gd.write(e);
00720 return e;
00721 }
00722
00723 };
00724
00726 template<typename Datatype, typename Metatype>
00727 class SingleDataContainerFactory:
00728 public PackageContainerFactory<Datatype,Metatype> {
00729 private:
00730 int nrep;
00731 Metatype * g;
00732
00733 protected:
00734 PackageContainer<Datatype,Metatype> * buildPC() const {
00735 SingleDataContainer<Datatype,Metatype> * gdc
00736 = new SingleDataContainer<Datatype,Metatype>(nrep);
00737 if (g) {
00738 gdc->initialize(*g);
00739 return gdc;
00740 }
00741 else {
00742 RVLException e;
00743 e<<"Error: SingleDataContainerFactory::buildPC\n";
00744 e<<"internal Metadata not initialized\n";
00745 throw e;
00746 }
00747 }
00748
00749 public:
00750 SingleDataContainerFactory(int _nrep=1): nrep(_nrep), g(NULL) {}
00751 SingleDataContainerFactory
00752 (SingleDataContainerFactory<Datatype,Metatype> const & f)
00753 : nrep(f.nrep), g(NULL) {
00754 if (f.g) g=new Metatype(*(f.g)); }
00755 ~SingleDataContainerFactory() { if (g) delete g; }
00756
00757 PackageContainerFactory<Datatype,Metatype> * clone() const {
00758 if (g) {
00759 SingleDataContainerFactory<Datatype,Metatype> * f
00760 = new SingleDataContainerFactory<Datatype,Metatype>;
00761 f->initialize(*g);
00762 return f;
00763 }
00764 RVLException e;
00765 e<<"Error: SingleDataContainerFactory::clone\n";
00766 e<<"cannot construct copy because not initialized\n";
00767 throw e;
00768 }
00769 void initialize(Metatype const & _g) { g = new Metatype(_g); }
00770
00771 bool compare( DataContainerFactory const & dcf) const {
00772 try {
00773 if (!g) {
00774 cerr<<"Warning: SingleDataContainerFactory::compare\n";
00775 cerr<<"cannot compare uninitialized factory to others\n";
00776 return false;
00777 }
00778 SingleDataContainerFactory<Datatype,Metatype> const * dcfptr = NULL;
00779 if ((dcfptr = dynamic_cast<SingleDataContainerFactory<Datatype,Metatype> const *>(dcfptr))) {
00780 if (!(dcfptr->g)) {
00781 cerr<<"Warning: GridDataContainerFactory::compare\n";
00782 cerr<<"cannot compare this to uninitialized factory\n";
00783 return false;
00784 }
00785 if ( *g == *(dcfptr->g)) return true;
00786 }
00787 }
00788 catch (RVLException & e) {
00789 e<<"\ncalled from SingleDataContainerFactory::compare\n";
00790 throw e;
00791 }
00792 }
00793
00794 bool isCompatible(DataContainer const & dc) const {
00795 try {
00796 if (!g) {
00797 cerr<<"Warning: SingleDataContainerFactory::isCompatible\n";
00798 cerr<<"cannot decide compatibility for uninitialized factory\n";
00799 return false;
00800 }
00801 SingleDataContainer<Datatype,Metatype> const * dcptr = NULL;
00802 if ((dcptr = dynamic_cast<SingleDataContainer<Datatype,Metatype> const *>(&dc)))
00803 if (*g == dcptr->getMetadata()) return true;
00804 return false;
00805 }
00806 catch (RVLException & e) {
00807 e<<"\ncalled from GridDataContainerFactory::isCompatible\n";
00808 throw e;
00809 }
00810 }
00811
00812 ostream & write(ostream & str) const {
00813 str<<"SingleDataContainerFactory";
00814 if (g) {
00815 str<<" using Metadata:\n";
00816 g->write(str);
00817 }
00818 else {
00819 str<<" (uninitialized)\n";
00820 }
00821 return str;
00822 }
00823
00824 };
00825
00826 }
00827
00828 #endif