]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
*** empty log message ***
authorageay <ageay>
Fri, 10 Dec 2010 15:56:43 +0000 (15:56 +0000)
committerageay <ageay>
Fri, 10 Dec 2010 15:56:43 +0000 (15:56 +0000)
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx
src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx
src/MEDCoupling_Swig/MEDCoupling.i
src/MEDCoupling_Swig/MEDCouplingBasicsTest.py

index 0a2710e785e46a99d1d40f5679c56aa3e370cc09..c4bf7ff74377f0000494e3a6ccde29e845e10e10 100644 (file)
@@ -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<DataArrayDouble> 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 && *w<oldNbOfTuples)
+      std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
+    else
+      throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
+  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<DataArrayInt> 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 && *w<oldNbOfTuples)
+      std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
+    else
+      throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
+  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
index 2a3427540273b0170700903a584dcb1caadeecee..0a43eb34e01364d3cd39ce57aef14af1602a45f6 100644 (file)
@@ -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<int>& 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);
index 830150dcd44350c604d2e7d71a24fc9e3a56ba30..87c89448009c86965974b569c0f767598b3b30d6 100644 (file)
@@ -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();
index 5937dbca4f3048440a874d160bb7ede7d6256e79..320778997ed655223f7ef0ca2e3cd40d9fb1c855 100644 (file)
@@ -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();
+}
index 4e138445e16251d10d5cb9e02f98be0fcdecbbb7..01ed711645b8ddfb3e3e14ff972284af9a22bdc2 100644 (file)
@@ -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<int> 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<double> 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<int> tmp=convertPyToNewIntArr2(li,&size);
+     DataArrayInt *ret=self->selectByTupleIdSafe(tmp,tmp+size);
+     return ret;
+   }
+
    DataArrayInt *keepSelectedComponents(PyObject *li) const throw(INTERP_KERNEL::Exception)
    {
      std::vector<int> 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<int> tmp=new int[sz];
+     self->getTuple(tupleId,tmp);
+     return convertIntArrToPyList(tmp,sz);
+   }
+
    static DataArrayInt *meld(PyObject *li) throw(INTERP_KERNEL::Exception)
    {
      std::vector<const DataArrayInt *> tmp;
index 7b0b63bb8370d3ea30e4dac53e4f46084559aa72..604476ed12a71cf24dc508f7c9c360126d2a294f 100644 (file)
@@ -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