From: ageay Date: Fri, 10 Dec 2010 15:56:43 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: MEDPartitioner_first_compilable_version~36 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=86413f7cca0239f43e28558c9c803be202bde695;p=tools%2Fmedcoupling.git *** empty log message *** --- diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index 0a2710e78..c4bf7ff74 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -403,6 +403,29 @@ DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const in return ret; } +/*! + * This method is equivalent to DataArrayInt::selectByTupleId except that an analyze to the content of input range to check that it will not lead to memory corruption ! + */ +DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); + int nbComp=getNumberOfComponents(); + int oldNbOfTuples=getNumberOfTuples(); + ret->alloc(std::distance(new2OldBg,new2OldEnd),nbComp); + ret->copyStringInfoFrom(*this); + double *pt=ret->getPointer(); + const double *srcPt=getConstPointer(); + int i=0; + for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++) + if(*w>=0 && *wgetNumberOfTuples) !"); + ret->copyStringInfoFrom(*this); + ret->incrRef(); + return ret; +} + /*! * This methods has a similar behaviour than std::string::substr. This method returns a newly created DataArrayInt that is part of this with same number of components. * The intervall is specified by [tupleIdBg,tupleIdEnd) except if tupleIdEnd ==-1 in this case the [tupleIdBg,this->end()) will be kept. @@ -1668,6 +1691,29 @@ DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new return ret; } +/*! + * This method is equivalent to DataArrayInt::selectByTupleId except that an analyze to the content of input range to check that it will not lead to memory corruption ! + */ +DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + int nbComp=getNumberOfComponents(); + int oldNbOfTuples=getNumberOfTuples(); + ret->alloc(std::distance(new2OldBg,new2OldEnd),nbComp); + ret->copyStringInfoFrom(*this); + int *pt=ret->getPointer(); + const int *srcPt=getConstPointer(); + int i=0; + for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++) + if(*w>=0 && *wgetNumberOfTuples) !"); + ret->copyStringInfoFrom(*this); + ret->incrRef(); + return ret; +} + /*! * This method checks that 'this' is with numberofcomponents == 1 and that it is equal to * stdext::iota() of size getNumberOfTuples. This method is particalary usefull for DataArrayInt instances diff --git a/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx index 2a3427540..0a43eb34e 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ b/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -144,6 +144,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayDouble *renumberR(const int *new2Old) const; MEDCOUPLING_EXPORT DataArrayDouble *renumberAndReduce(const int *old2New, int newNbOfTuple) const; MEDCOUPLING_EXPORT DataArrayDouble *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const; + MEDCOUPLING_EXPORT DataArrayDouble *selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *substr(int tupleIdBg, int tupleIdEnd=-1) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception); @@ -243,6 +244,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayInt *renumberR(const int *new2Old) const; MEDCOUPLING_EXPORT DataArrayInt *renumberAndReduce(const int *old2NewBg, int newNbOfTuple) const; MEDCOUPLING_EXPORT DataArrayInt *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const; + MEDCOUPLING_EXPORT DataArrayInt *selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool isIdentity() const; MEDCOUPLING_EXPORT bool isUniform(int val) const; MEDCOUPLING_EXPORT DataArrayInt *substr(int tupleIdBg, int tupleIdEnd=-1) const throw(INTERP_KERNEL::Exception); diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx index 830150dcd..87c894480 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx @@ -168,6 +168,7 @@ namespace ParaMEDMEM CPPUNIT_TEST( testDAIBuildUnion1 ); CPPUNIT_TEST( testDAIBuildIntersection1 ); CPPUNIT_TEST( testDAIDeltaShiftIndex1 ); + CPPUNIT_TEST( testDaDoubleSelectByTupleIdSafe1 ); //MEDCouplingBasicsTestInterp.cxx CPPUNIT_TEST( test2DInterpP0P0_1 ); CPPUNIT_TEST( test2DInterpP0P0PL_1 ); @@ -364,6 +365,7 @@ namespace ParaMEDMEM void testDAIBuildUnion1(); void testDAIBuildIntersection1(); void testDAIDeltaShiftIndex1(); + void testDaDoubleSelectByTupleIdSafe1(); //MEDCouplingBasicsTestInterp.cxx void test2DInterpP0P0_1(); void test2DInterpP0P0PL_1(); diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx index 5937dbca4..320778997 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx @@ -3897,3 +3897,47 @@ void MEDCouplingBasicsTest::testDAIDeltaShiftIndex1() a->decrRef(); } +void MEDCouplingBasicsTest::testDaDoubleSelectByTupleIdSafe1() +{ + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(7,2); + a->setInfoOnComponent(0,"toto"); + a->setInfoOnComponent(1,"tata"); + const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; + std::copy(arr1,arr1+14,a->getPointer()); + // + const int arr2[7]={4,2,0,6,5}; + DataArrayDouble *b=a->selectByTupleIdSafe(arr2,arr2+5); + CPPUNIT_ASSERT_EQUAL(5,b->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); + CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto"); + CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata"); + const double expected1[10]={5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1}; + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); + const int arr4[5]={4,-1,0,6,5}; + CPPUNIT_ASSERT_THROW(a->selectByTupleIdSafe(arr4,arr4+5),INTERP_KERNEL::Exception); + const int arr5[5]={4,2,0,6,7}; + CPPUNIT_ASSERT_THROW(a->selectByTupleIdSafe(arr5,arr5+5),INTERP_KERNEL::Exception); + b->decrRef(); + a->decrRef(); + // + DataArrayInt *c=DataArrayInt::New(); + c->alloc(7,2); + c->setInfoOnComponent(0,"toto"); + c->setInfoOnComponent(1,"tata"); + const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; + std::copy(arr3,arr3+14,c->getPointer()); + DataArrayInt *d=c->selectByTupleIdSafe(arr2,arr2+5); + CPPUNIT_ASSERT_EQUAL(5,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents()); + CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto"); + CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata"); + const int expected2[10]={5,15,3,13,1,11,7,17,6,16}; + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i)); + CPPUNIT_ASSERT_THROW(c->selectByTupleIdSafe(arr4,arr4+5),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(c->selectByTupleIdSafe(arr5,arr5+5),INTERP_KERNEL::Exception); + c->decrRef(); + d->decrRef(); +} diff --git a/src/MEDCoupling_Swig/MEDCoupling.i b/src/MEDCoupling_Swig/MEDCoupling.i index 4e138445e..01ed71164 100644 --- a/src/MEDCoupling_Swig/MEDCoupling.i +++ b/src/MEDCoupling_Swig/MEDCoupling.i @@ -34,6 +34,8 @@ #include "MEDCouplingGaussLocalization.hxx" #include "MEDCouplingTypemaps.i" +#include "InterpKernelAutoPtr.hxx" + using namespace ParaMEDMEM; using namespace INTERP_KERNEL; %} @@ -99,6 +101,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::DataArrayInt::changeNbOfComponents; %newobject ParaMEDMEM::DataArrayInt::keepSelectedComponents; %newobject ParaMEDMEM::DataArrayInt::selectByTupleId; +%newobject ParaMEDMEM::DataArrayInt::selectByTupleIdSafe; %newobject ParaMEDMEM::DataArrayInt::renumber; %newobject ParaMEDMEM::DataArrayInt::renumberR; %newobject ParaMEDMEM::DataArrayInt::renumberAndReduce; @@ -131,6 +134,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::DataArrayDouble::keepSelectedComponents; %newobject ParaMEDMEM::DataArrayDouble::getIdsInRange; %newobject ParaMEDMEM::DataArrayDouble::selectByTupleId; +%newobject ParaMEDMEM::DataArrayDouble::selectByTupleIdSafe; %newobject ParaMEDMEM::DataArrayDouble::applyFunc; %newobject ParaMEDMEM::DataArrayDouble::doublyContractedProduct; %newobject ParaMEDMEM::DataArrayDouble::determinant; @@ -1011,6 +1015,14 @@ namespace ParaMEDMEM return ret; } + DataArrayDouble *selectByTupleIdSafe(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + int size; + INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); + DataArrayDouble *ret=self->selectByTupleIdSafe(tmp,tmp+size); + return ret; + } + PyObject *getMaxValue() const throw(INTERP_KERNEL::Exception) { int tmp; @@ -1082,6 +1094,14 @@ namespace ParaMEDMEM convertPyToNewIntArr3(li,tmp); self->setSelectedComponents(a,tmp); } + + PyObject *getTuple(int tupleId) throw(INTERP_KERNEL::Exception) + { + int sz=self->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr tmp=new double[sz]; + self->getTuple(tupleId,tmp); + return convertDblArrToPyList(tmp,sz); + } static DataArrayDouble *aggregate(PyObject *li) throw(INTERP_KERNEL::Exception) { @@ -1219,6 +1239,14 @@ namespace ParaMEDMEM return ret; } + DataArrayInt *selectByTupleIdSafe(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + int size; + INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); + DataArrayInt *ret=self->selectByTupleIdSafe(tmp,tmp+size); + return ret; + } + DataArrayInt *keepSelectedComponents(PyObject *li) const throw(INTERP_KERNEL::Exception) { std::vector tmp; @@ -1233,6 +1261,14 @@ namespace ParaMEDMEM self->setSelectedComponents(a,tmp); } + PyObject *getTuple(int tupleId) throw(INTERP_KERNEL::Exception) + { + int sz=self->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr tmp=new int[sz]; + self->getTuple(tupleId,tmp); + return convertIntArrToPyList(tmp,sz); + } + static DataArrayInt *meld(PyObject *li) throw(INTERP_KERNEL::Exception) { std::vector tmp; diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py index 7b0b63bb8..604476ed1 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -4542,6 +4542,11 @@ class MEDCouplingBasicsTest(unittest.TestCase): arr1=[1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.] a1=DataArrayDouble.New(); a1.setValues(arr1,5,4); + expp=[21.,22.,23.,24.] + self.assertEqual(4,len(a1.getTuple(2))); + for i in xrange(4): + self.assertAlmostEqual(expp[i],a1.getTuple(2)[i],12) + pass a1.setInfoOnComponent(0,"aaaa"); a1.setInfoOnComponent(1,"bbbb"); a1.setInfoOnComponent(2,"cccc"); @@ -4561,6 +4566,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertAlmostEqual(expected1[i],a2.getIJ(0,i),14); pass a3=a1.convertToIntArr(); + self.assertEqual([21,22,23,24],a3.getTuple(2)) a4=a3.keepSelectedComponents(arr2V); self.assertEqual(6,a4.getNumberOfComponents()); self.assertEqual(5,a4.getNumberOfTuples()); @@ -5396,6 +5402,46 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertEqual(expected1[i],b.getIJ(0,i)); pass pass + + def testDaDoubleSelectByTupleIdSafe1(self): + a=DataArrayDouble.New(); + arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] + a.setValues(arr1,7,2); + a.setInfoOnComponent(0,"toto"); + a.setInfoOnComponent(1,"tata"); + # + arr2=[4,2,0,6,5] + b=a.selectByTupleIdSafe(arr2); + self.assertEqual(5,b.getNumberOfTuples()); + self.assertEqual(2,b.getNumberOfComponents()); + self.assertTrue(b.getInfoOnComponent(0)=="toto"); + self.assertTrue(b.getInfoOnComponent(1)=="tata"); + expected1=[5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1] + for i in xrange(10): + self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); + pass + arr4=[4,-1,0,6,5] + self.assertRaises(Exception,a.selectByTupleIdSafe,arr4); + arr5=[4,2,0,6,7] + self.assertRaises(Exception,a.selectByTupleIdSafe,arr5); + # + c=DataArrayInt.New(); + arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] + c.setValues(arr3,7,2); + c.setInfoOnComponent(0,"toto"); + c.setInfoOnComponent(1,"tata"); + d=c.selectByTupleIdSafe(arr2); + self.assertEqual(5,d.getNumberOfTuples()); + self.assertEqual(2,d.getNumberOfComponents()); + self.assertTrue(d.getInfoOnComponent(0)=="toto"); + self.assertTrue(d.getInfoOnComponent(1)=="tata"); + expected2=[5,15,3,13,1,11,7,17,6,16] + for i in xrange(10): + self.assertEqual(expected2[i],d.getIJ(0,i)); + pass + self.assertRaises(Exception,c.selectByTupleIdSafe,arr4); + self.assertRaises(Exception,c.selectByTupleIdSafe,arr5); + pass def setUp(self): pass