Salome HOME
Merge from MrgToV7main1804
[modules/med.git] / src / MEDCoupling / MEDCouplingMemArrayChar.cxx
index e52d0cafa580d574f8f7a97f8c77f2c26435313d..0906a91ad1e9173dc6e2106e54d67cc967319329 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2013  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -52,7 +52,7 @@ void DataArrayChar::checkAllocated() const throw(INTERP_KERNEL::Exception)
 
 std::size_t DataArrayChar::getHeapMemorySize() const
 {
-  std::size_t sz=(std::size_t)_mem.getNbOfElemAllocated();
+  std::size_t sz=_mem.getNbOfElemAllocated();
   return DataArray::getHeapMemorySize()+sz;
 }
 
@@ -91,14 +91,14 @@ void DataArrayChar::setInfoAndChangeNbOfCompo(const std::vector<std::string>& in
 int DataArrayChar::getHashCode() const throw(INTERP_KERNEL::Exception)
 {
   checkAllocated();
-  int nbOfElems=getNbOfElems();
+  std::size_t nbOfElems=getNbOfElems();
   int ret=nbOfElems*65536;
   int delta=3;
   if(nbOfElems>48)
     delta=nbOfElems/8;
   int ret0=0;
   const char *pt=begin();
-  for(int i=0;i<nbOfElems;i+=delta)
+  for(std::size_t i=0;i<nbOfElems;i+=delta)
     ret0+=pt[i];
   return ret+ret0;
 }
@@ -126,10 +126,10 @@ void DataArrayChar::cpyFrom(const DataArrayChar& other) throw(INTERP_KERNEL::Exc
   int nbOfTuples=other.getNumberOfTuples();
   int nbOfComp=other.getNumberOfComponents();
   allocIfNecessary(nbOfTuples,nbOfComp);
-  int nbOfElems=nbOfTuples*nbOfComp;
+  std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
   char *pt=getPointer();
   const char *ptI=other.getConstPointer();
-  for(int i=0;i<nbOfElems;i++)
+  for(std::size_t i=0;i<nbOfElems;i++)
     pt[i]=ptI[i];
   copyStringInfoFrom(other);
 }
@@ -142,7 +142,7 @@ void DataArrayChar::cpyFrom(const DataArrayChar& other) throw(INTERP_KERNEL::Exc
  * 
  * \sa DataArrayChar::pack, DataArrayChar::pushBackSilent, DataArrayChar::pushBackValsSilent
  */
-void DataArrayChar::reserve(int nbOfElems) throw(INTERP_KERNEL::Exception)
+void DataArrayChar::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
 {
   int nbCompo=getNumberOfComponents();
   if(nbCompo==1)
@@ -258,7 +258,7 @@ void DataArrayChar::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exc
   if(nbOfTuple<0 || nbOfCompo<0)
     throw INTERP_KERNEL::Exception("DataArrayChar::alloc : request for negative length of data !");
   _info_on_compo.resize(nbOfCompo);
-  _mem.alloc(nbOfCompo*nbOfTuple);
+  _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
   declareAsNew();
 }
 
@@ -301,6 +301,18 @@ bool DataArrayChar::isEqualWithoutConsideringStr(const DataArrayChar& other) con
   return _mem.isEqual(other._mem,0,tmp);
 }
 
+/*!
+ * Reverse the array values.
+ *  \throw If \a this->getNumberOfComponents() < 1.
+ *  \throw If \a this is not allocated.
+ */
+void DataArrayChar::reverse() throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  _mem.reverse(getNumberOfComponents());
+  declareAsNew();
+}
+
 /*!
  * Assign zero to all values in \a this array. To know more on filling arrays see
  * \ref MEDCouplingArrayFill.
@@ -354,7 +366,7 @@ std::string DataArrayChar::reprZip() const throw(INTERP_KERNEL::Exception)
 void DataArrayChar::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
 {
   checkAllocated();
-  _mem.reAlloc(getNumberOfComponents()*nbOfTuples);
+  _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
   declareAsNew();
 }
 
@@ -368,7 +380,7 @@ DataArrayInt *DataArrayChar::convertToIntArr() const throw(INTERP_KERNEL::Except
   checkAllocated();
   DataArrayInt *ret=DataArrayInt::New();
   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
-  int nbOfVals=getNbOfElems();
+  std::size_t nbOfVals=getNbOfElems();
   const char *src=getConstPointer();
   int *dest=ret->getPointer();
   std::copy(src,src+nbOfVals,dest);
@@ -568,7 +580,7 @@ DataArrayChar *DataArrayChar::selectByTupleId2(int bg, int end2, int step) const
   checkAllocated();
   MEDCouplingAutoRefCountObjectPtr<DataArrayChar> ret=buildEmptySpecializedDAChar();
   int nbComp=getNumberOfComponents();
-  int newNbOfTuples=GetNumberOfItemGivenBES(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
+  int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
   ret->alloc(newNbOfTuples,nbComp);
   char *pt=ret->getPointer();
   const char *srcPt=getConstPointer()+bg*nbComp;
@@ -605,19 +617,64 @@ bool DataArrayChar::isUniform(char val) const throw(INTERP_KERNEL::Exception)
  *  \param [in] newNbOfComp - number of components for \a this array to have.
  *  \throw If \a this is not allocated
  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
+ *  \throw If \a newNbOfCompo is lower than 1.
+ *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
  *  \warning This method erases all (name and unit) component info set before!
  */
 void DataArrayChar::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
 {
   checkAllocated();
-  int nbOfElems=getNbOfElems();
+  if(newNbOfCompo<1)
+    throw INTERP_KERNEL::Exception("DataArrayChar::rearrange : input newNbOfCompo must be > 0 !");
+  std::size_t nbOfElems=getNbOfElems();
   if(nbOfElems%newNbOfCompo!=0)
     throw INTERP_KERNEL::Exception("DataArrayChar::rearrange : nbOfElems%newNbOfCompo!=0 !");
+  if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
+    throw INTERP_KERNEL::Exception("DataArrayChar::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
   _info_on_compo.clear();
   _info_on_compo.resize(newNbOfCompo);
   declareAsNew();
 }
 
+/*!
+ * Returns a shorten copy of \a this array. The new DataArrayChar contains all
+ * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
+ * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
+ * This method is a specialization of selectByTupleId2().
+ *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
+ *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
+ *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
+ *  \return DataArrayChar * - the new instance of DataArrayChar that the caller
+ *          is to delete using decrRef() as it is no more needed.
+ *  \throw If \a tupleIdBg < 0.
+ *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
+    \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
+ *  \sa DataArrayChar::selectByTupleId2
+ */
+DataArrayChar *DataArrayChar::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  int nbt=getNumberOfTuples();
+  if(tupleIdBg<0)
+    throw INTERP_KERNEL::Exception("DataArrayChar::substr : The tupleIdBg parameter must be greater than 0 !");
+  if(tupleIdBg>nbt)
+    throw INTERP_KERNEL::Exception("DataArrayChar::substr : The tupleIdBg parameter is greater than number of tuples !");
+  int trueEnd=tupleIdEnd;
+  if(tupleIdEnd!=-1)
+    {
+      if(tupleIdEnd>nbt)
+        throw INTERP_KERNEL::Exception("DataArrayChar::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
+    }
+  else
+    trueEnd=nbt;
+  int nbComp=getNumberOfComponents();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayChar> ret=buildEmptySpecializedDAChar();
+  ret->alloc(trueEnd-tupleIdBg,nbComp);
+  ret->copyStringInfoFrom(*this);
+  std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
+  return ret.retn();
+}
+
 /*!
  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
@@ -777,7 +834,7 @@ void DataArrayChar::setPartOfValues1(const DataArrayChar *a, int bgTuples, int e
   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
   bool assignTech=true;
-  if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
+  if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
     {
       if(strictCompoCompare)
         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
@@ -895,7 +952,7 @@ void DataArrayChar::setPartOfValues2(const DataArrayChar *a, const int *bgTuples
   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
   int newNbOfComp=(int)std::distance(bgComp,endComp);
   bool assignTech=true;
-  if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
+  if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
     {
       if(strictCompoCompare)
         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
@@ -914,7 +971,7 @@ void DataArrayChar::setPartOfValues2(const DataArrayChar *a, const int *bgTuples
           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
             {    
-              pt[(*w)*nbComp+(*z)]=*srcPt;
+              pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
             }
         }
     }
@@ -926,7 +983,7 @@ void DataArrayChar::setPartOfValues2(const DataArrayChar *a, const int *bgTuples
           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
             {    
-              pt[(*w)*nbComp+(*z)]=*srcPt2;
+              pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
             }
         }
     }
@@ -964,7 +1021,7 @@ void DataArrayChar::setPartOfValuesSimple2(char a, const int *bgTuples, const in
     for(const int *z=bgComp;z!=endComp;z++)
       {
         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
-        pt[(*w)*nbComp+(*z)]=a;
+        pt[(std::size_t)(*w)*nbComp+(*z)]=a;
       }
 }
 
@@ -1025,7 +1082,7 @@ void DataArrayChar::setPartOfValues3(const DataArrayChar *a, const int *bgTuples
   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
   bool assignTech=true;
-  if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
+  if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
     {
       if(strictCompoCompare)
         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
@@ -1043,7 +1100,7 @@ void DataArrayChar::setPartOfValues3(const DataArrayChar *a, const int *bgTuples
         for(int j=0;j<newNbOfComp;j++,srcPt++)
           {
             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
-            pt[(*w)*nbComp+j*stepComp]=*srcPt;
+            pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
           }
     }
   else
@@ -1054,7 +1111,7 @@ void DataArrayChar::setPartOfValues3(const DataArrayChar *a, const int *bgTuples
           for(int j=0;j<newNbOfComp;j++,srcPt2++)
             {
               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
-              pt[(*w)*nbComp+j*stepComp]=*srcPt2;
+              pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
             }
         }
     }
@@ -1116,7 +1173,7 @@ void DataArrayChar::setPartOfValues4(const DataArrayChar *a, int bgTuples, int e
   int nbOfTuples=getNumberOfTuples();
   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
   bool assignTech=true;
-  if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
+  if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
     {
       if(strictCompoCompare)
         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
@@ -1245,7 +1302,7 @@ char DataArrayChar::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNE
       std::ostringstream oss; oss << "DataArrayChar::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
-  return _mem[tupleId*((int)_info_on_compo.size())+compoId];
+  return _mem[tupleId*_info_on_compo.size()+compoId];
 }
 
 /*!
@@ -1325,7 +1382,7 @@ int DataArrayChar::search(const std::vector<char>& vals) const throw(INTERP_KERN
   if(nbOfCompo!=1)
     throw INTERP_KERNEL::Exception("DataArrayChar::search : works only for DataArrayChar instance with one component !");
   const char *cptr=getConstPointer();
-  int nbOfVals=getNbOfElems();
+  std::size_t nbOfVals=getNbOfElems();
   const char *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
   if(loc!=cptr+nbOfVals)
     return std::distance(cptr,loc);
@@ -1356,7 +1413,7 @@ int DataArrayChar::locateTuple(const std::vector<char>& tupl) const throw(INTERP
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
   const char *cptr=getConstPointer();
-  int nbOfVals=getNbOfElems();
+  std::size_t nbOfVals=getNbOfElems();
   for(const char *work=cptr;work!=cptr+nbOfVals;)
     {
       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
@@ -1696,14 +1753,14 @@ DataArrayChar *DataArrayChar::Meld(const std::vector<const DataArrayChar *>& arr
 void DataArrayChar::useArray(const char *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
 {
   _info_on_compo.resize(nbOfCompo);
-  _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
+  _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
   declareAsNew();
 }
 
 void DataArrayChar::useExternalArrayWithRWAccess(const char *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
 {
   _info_on_compo.resize(nbOfCompo);
-  _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
+  _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
   declareAsNew();
 }
 
@@ -1790,7 +1847,18 @@ void DataArrayByte::reprZipStream(std::ostream& stream) const throw(INTERP_KERNE
 void DataArrayByte::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
 {
   DataArray::reprWithoutNameStream(stream);
-  _mem.repr(getNumberOfComponents(),stream);
+  if(_mem.reprHeader(getNumberOfComponents(),stream))
+    {
+      const char *data=begin();
+      int nbOfTuples=getNumberOfTuples();
+      int nbCompo=getNumberOfComponents();
+      for(int i=0;i<nbOfTuples;i++,data+=nbCompo)
+        {
+          stream << "Tuple #" << i << " : ";
+          std::copy(data,data+nbCompo,std::ostream_iterator<int>(stream," "));//it is not a bug int here not char because it is not ASCII here contrary to DataArrayAsciiChar
+          stream << "\n";
+        }
+    }
 }
 
 void DataArrayByte::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
@@ -1816,6 +1884,64 @@ void DataArrayByte::reprCppStream(const char *varName, std::ostream& stream) con
   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
 }
 
+/*!
+ * Method that gives a quick overvien of \a this for python.
+ */
+void DataArrayByte::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
+{
+  static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
+  stream << "DataArrayByte C++ instance at " << this << ". ";
+  if(isAllocated())
+    {
+      int nbOfCompo=(int)_info_on_compo.size();
+      if(nbOfCompo>=1)
+        {
+          int nbOfTuples=getNumberOfTuples();
+          stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
+          reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
+        }
+      else
+        stream << "Number of components : 0.";
+    }
+  else
+    stream << "*** No data allocated ****";
+}
+
+void DataArrayByte::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
+{
+  const char *data=begin();
+  int nbOfTuples=getNumberOfTuples();
+  int nbOfCompo=(int)_info_on_compo.size();
+  std::ostringstream oss2; oss2 << "[";
+  std::string oss2Str(oss2.str());
+  bool isFinished=true;
+  for(int i=0;i<nbOfTuples && isFinished;i++)
+    {
+      if(nbOfCompo>1)
+        {
+          oss2 << "(";
+          for(int j=0;j<nbOfCompo;j++,data++)
+            {
+              oss2 << (int)*data;
+              if(j!=nbOfCompo-1) oss2 << ", ";
+            }
+          oss2 << ")";
+        }
+      else
+        { oss2 << (int)*data; data++; }
+      if(i!=nbOfTuples-1) oss2 << ", ";
+      std::string oss3Str(oss2.str());
+      if(oss3Str.length()<maxNbOfByteInRepr)
+        oss2Str=oss3Str;
+      else
+        isFinished=false;
+    }
+  stream << oss2Str;
+  if(!isFinished)
+    stream << "... ";
+  stream << "]";
+}
+
 bool DataArrayByte::isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
 {
   const DataArrayByte *otherC=dynamic_cast<const DataArrayByte *>(&other);
@@ -2090,6 +2216,72 @@ void DataArrayAsciiChar::reprCppStream(const char *varName, std::ostream& stream
   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
 }
 
+/*!
+ * Method that gives a quick overvien of \a this for python.
+ */
+void DataArrayAsciiChar::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
+{
+  static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
+  stream << "DataArrayAsciiChar C++ instance at " << this << ". ";
+  if(isAllocated())
+    {
+      int nbOfCompo=(int)_info_on_compo.size();
+      if(nbOfCompo>=1)
+        {
+          int nbOfTuples=getNumberOfTuples();
+          stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
+          reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
+        }
+      else
+        stream << "Number of components : 0.";
+    }
+  else
+    stream << "*** No data allocated ****";
+}
+
+void DataArrayAsciiChar::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
+{
+  const char *data=begin();
+  int nbOfTuples=getNumberOfTuples();
+  int nbOfCompo=(int)_info_on_compo.size();
+  std::ostringstream oss2; oss2 << "[";
+  std::string oss2Str(oss2.str());
+  bool isFinished=true;
+  for(int i=0;i<nbOfTuples && isFinished;i++)
+    {
+      bool isAscii=true;
+      for(int j=0;j<nbOfCompo;j++)
+        if(data[j]<32) isAscii=false;
+      if(isAscii)
+        {
+          oss2 << "\'";
+          for(int j=0;j<nbOfCompo;j++,data++)
+            oss2 << *data;
+          oss2 << "\'";
+        }
+      else
+        {
+          oss2 << "(";
+          for(int j=0;j<nbOfCompo;j++,data++)
+            {
+              oss2 << (int)*data;
+              if(j!=nbOfCompo-1) oss2 << ", ";
+            }
+          oss2 << ")";
+        }
+      if(i!=nbOfTuples-1) oss2 << ", ";
+      std::string oss3Str(oss2.str());
+      if(oss3Str.length()<maxNbOfByteInRepr)
+        oss2Str=oss3Str;
+      else
+        isFinished=false;
+    }
+  stream << oss2Str;
+  if(!isFinished)
+    stream << "... ";
+  stream << "]";
+}
+
 bool DataArrayAsciiChar::isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
 {
   const DataArrayAsciiChar *otherC=dynamic_cast<const DataArrayAsciiChar *>(&other);