Salome HOME
Merge from V6_main (dev of Anthony GEAY) 11/06/2013
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArrayChar.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingMemArray.txx"
22 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
23
24 #include <set>
25 #include <cmath>
26 #include <limits>
27 #include <numeric>
28 #include <algorithm>
29 #include <functional>
30
31 using namespace ParaMEDMEM;
32
33 /*!
34  * Checks if raw data is allocated. Read more on the raw data
35  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
36  *  \return bool - \a true if the raw data is allocated, \a false else.
37  */
38 bool DataArrayChar::isAllocated() const throw(INTERP_KERNEL::Exception)
39 {
40   return getConstPointer()!=0;
41 }
42
43 /*!
44  * Checks if raw data is allocated and throws an exception if it is not the case.
45  *  \throw If the raw data is not allocated.
46  */
47 void DataArrayChar::checkAllocated() const throw(INTERP_KERNEL::Exception)
48 {
49   if(!isAllocated())
50     throw INTERP_KERNEL::Exception("DataArrayChar::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
51 }
52
53 std::size_t DataArrayChar::getHeapMemorySize() const
54 {
55   std::size_t sz=_mem.getNbOfElemAllocated();
56   return DataArray::getHeapMemorySize()+sz;
57 }
58
59 /*!
60  * Returns an integer value characterizing \a this array, which is useful for a quick
61  * comparison of many instances of DataArrayInt.
62  *  \return int - the hash value.
63  *  \throw If \a this is not allocated.
64  */
65 int DataArrayChar::getHashCode() const throw(INTERP_KERNEL::Exception)
66 {
67   checkAllocated();
68   std::size_t nbOfElems=getNbOfElems();
69   int ret=nbOfElems*65536;
70   int delta=3;
71   if(nbOfElems>48)
72     delta=nbOfElems/8;
73   int ret0=0;
74   const char *pt=begin();
75   for(std::size_t i=0;i<nbOfElems;i+=delta)
76     ret0+=pt[i];
77   return ret+ret0;
78 }
79
80 /*!
81  * Checks the number of tuples.
82  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
83  *  \throw If \a this is not allocated.
84  */
85 bool DataArrayChar::empty() const throw(INTERP_KERNEL::Exception)
86 {
87   checkAllocated();
88   return getNumberOfTuples()==0;
89 }
90
91 /*!
92  * Copies all the data from another DataArrayChar. For more info see
93  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
94  *  \param [in] other - another instance of DataArrayChar to copy data from.
95  *  \throw If the \a other is not allocated.
96  */
97 void DataArrayChar::cpyFrom(const DataArrayChar& other) throw(INTERP_KERNEL::Exception)
98 {
99   other.checkAllocated();
100   int nbOfTuples=other.getNumberOfTuples();
101   int nbOfComp=other.getNumberOfComponents();
102   allocIfNecessary(nbOfTuples,nbOfComp);
103   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
104   char *pt=getPointer();
105   const char *ptI=other.getConstPointer();
106   for(std::size_t i=0;i<nbOfElems;i++)
107     pt[i]=ptI[i];
108   copyStringInfoFrom(other);
109 }
110
111 /*!
112  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
113  * If \a this has already been allocated, this method checks that \a this has only one component. If not an INTERP_KERNEL::Exception will be thrown.
114  * If \a this has not already been allocated, number of components is set to one.
115  * This method allows to reduce number of reallocations on invokation of DataArrayChar::pushBackSilent and DataArrayChar::pushBackValsSilent on \a this.
116  * 
117  * \sa DataArrayChar::pack, DataArrayChar::pushBackSilent, DataArrayChar::pushBackValsSilent
118  */
119 void DataArrayChar::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
120 {
121   int nbCompo=getNumberOfComponents();
122   if(nbCompo==1)
123     {
124       _mem.reserve(nbOfElems);
125     }
126   else if(nbCompo==0)
127     {
128       _mem.reserve(nbOfElems);
129       _info_on_compo.resize(1);
130     }
131   else
132     throw INTERP_KERNEL::Exception("DataArrayChar::reserve : not available for DataArrayChar with number of components different than 1 !");
133 }
134
135 /*!
136  * This method adds at the end of \a this the single value \a val. This method do \b not update its time label to avoid useless incrementation
137  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
138  *
139  * \param [in] val the value to be added in \a this
140  * \throw If \a this has already been allocated with number of components different from one.
141  * \sa DataArrayChar::pushBackValsSilent
142  */
143 void DataArrayChar::pushBackSilent(char val) throw(INTERP_KERNEL::Exception)
144 {
145   int nbCompo=getNumberOfComponents();
146   if(nbCompo==1)
147     _mem.pushBack(val);
148   else if(nbCompo==0)
149     {
150       _info_on_compo.resize(1);
151       _mem.pushBack(val);
152     }
153   else
154     throw INTERP_KERNEL::Exception("DataArrayChar::pushBackSilent : not available for DataArrayChar with number of components different than 1 !");
155 }
156
157 /*!
158  * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation
159  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
160  *
161  *  \param [in] valsBg - an array of values to push at the end of \this.
162  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
163  *              the last value of \a valsBg is \a valsEnd[ -1 ].
164  * \throw If \a this has already been allocated with number of components different from one.
165  * \sa DataArrayChar::pushBackSilent
166  */
167 void DataArrayChar::pushBackValsSilent(const char *valsBg, const char *valsEnd) throw(INTERP_KERNEL::Exception)
168 {
169   int nbCompo=getNumberOfComponents();
170   if(nbCompo==1)
171     _mem.insertAtTheEnd(valsBg,valsEnd);
172   else if(nbCompo==0)
173     {
174       _info_on_compo.resize(1);
175       _mem.insertAtTheEnd(valsBg,valsEnd);
176     }
177   else
178     throw INTERP_KERNEL::Exception("DataArrayChar::pushBackValsSilent : not available for DataArrayChar with number of components different than 1 !");
179 }
180
181 /*!
182  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
183  * \throw If \a this is already empty.
184  * \throw If \a this has number of components different from one.
185  */
186 char DataArrayChar::popBackSilent() throw(INTERP_KERNEL::Exception)
187 {
188   if(getNumberOfComponents()==1)
189     return _mem.popBack();
190   else
191     throw INTERP_KERNEL::Exception("DataArrayChar::popBackSilent : not available for DataArrayChar with number of components different than 1 !");
192 }
193
194 /*!
195  * This method \b do \b not modify content of \a this. It only modify its memory footprint if the allocated memory is to high regarding real data to store.
196  *
197  * \sa DataArrayChar::getHeapMemorySize, DataArrayChar::reserve
198  */
199 void DataArrayChar::pack() const throw(INTERP_KERNEL::Exception)
200 {
201   _mem.pack();
202 }
203
204 /*!
205  * Allocates the raw data in memory. If exactly as same memory as needed already
206  * allocated, it is not re-allocated.
207  *  \param [in] nbOfTuple - number of tuples of data to allocate.
208  *  \param [in] nbOfCompo - number of components of data to allocate.
209  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
210  */
211 void DataArrayChar::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
212 {
213   if(isAllocated())
214     {
215       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
216         alloc(nbOfTuple,nbOfCompo);
217     }
218   else
219     alloc(nbOfTuple,nbOfCompo);
220 }
221
222 /*!
223  * Allocates the raw data in memory. If the memory was already allocated, then it is
224  * freed and re-allocated. See an example of this method use
225  * \ref MEDCouplingArraySteps1WC "here".
226  *  \param [in] nbOfTuple - number of tuples of data to allocate.
227  *  \param [in] nbOfCompo - number of components of data to allocate.
228  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
229  */
230 void DataArrayChar::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
231 {
232   if(nbOfTuple<0 || nbOfCompo<0)
233     throw INTERP_KERNEL::Exception("DataArrayChar::alloc : request for negative length of data !");
234   _info_on_compo.resize(nbOfCompo);
235   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
236   declareAsNew();
237 }
238
239 /*!
240  * Checks if \a this and another DataArrayChar are fully equal. For more info see
241  * \ref MEDCouplingArrayBasicsCompare.
242  *  \param [in] other - an instance of DataArrayChar to compare with \a this one.
243  *  \return bool - \a true if the two arrays are equal, \a false else.
244  */
245 bool DataArrayChar::isEqual(const DataArrayChar& other) const throw(INTERP_KERNEL::Exception)
246 {
247   std::string tmp;
248   return isEqualIfNotWhy(other,tmp);
249 }
250
251 /*!
252  * Equivalent to DataArrayChar::isEqual except that if false the reason of
253  * mismatch is given.
254  * 
255  * \param [in] other the instance to be compared with \a this
256  * \param [out] reason In case of inequality returns the reason.
257  * \sa DataArrayChar::isEqual
258  */
259 bool DataArrayChar::isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
260 {
261   if(!areInfoEqualsIfNotWhy(other,reason))
262     return false;
263   return _mem.isEqual(other._mem,0,reason);
264 }
265
266 /*!
267  * Checks if values of \a this and another DataArrayChar are equal. For more info see
268  * \ref MEDCouplingArrayBasicsCompare.
269  *  \param [in] other - an instance of DataArrayChar to compare with \a this one.
270  *  \return bool - \a true if the values of two arrays are equal, \a false else.
271  */
272 bool DataArrayChar::isEqualWithoutConsideringStr(const DataArrayChar& other) const throw(INTERP_KERNEL::Exception)
273 {
274   std::string tmp;
275   return _mem.isEqual(other._mem,0,tmp);
276 }
277
278 /*!
279  * Reverse the array values.
280  *  \throw If \a this->getNumberOfComponents() < 1.
281  *  \throw If \a this is not allocated.
282  */
283 void DataArrayChar::reverse() throw(INTERP_KERNEL::Exception)
284 {
285   checkAllocated();
286   _mem.reverse(getNumberOfComponents());
287   declareAsNew();
288 }
289
290 /*!
291  * Assign zero to all values in \a this array. To know more on filling arrays see
292  * \ref MEDCouplingArrayFill.
293  * \throw If \a this is not allocated.
294  */
295 void DataArrayChar::fillWithZero() throw(INTERP_KERNEL::Exception)
296 {
297   checkAllocated();
298   _mem.fillWithValue(0);
299   declareAsNew();
300 }
301
302 /*!
303  * Assign \a val to all values in \a this array. To know more on filling arrays see
304  * \ref MEDCouplingArrayFill.
305  *  \param [in] val - the value to fill with.
306  *  \throw If \a this is not allocated.
307  */
308 void DataArrayChar::fillWithValue(char val) throw(INTERP_KERNEL::Exception)
309 {
310   checkAllocated();
311   _mem.fillWithValue(val);
312   declareAsNew();
313 }
314
315 /*!
316  * Returns a textual and human readable representation of \a this instance of
317  * DataArrayChar. This text is shown when a DataArrayChar is printed in Python.
318  *  \return std::string - text describing \a this DataArrayChar.
319  */
320 std::string DataArrayChar::repr() const throw(INTERP_KERNEL::Exception)
321 {
322   std::ostringstream ret;
323   reprStream(ret);
324   return ret.str();
325 }
326
327 std::string DataArrayChar::reprZip() const throw(INTERP_KERNEL::Exception)
328 {
329   std::ostringstream ret;
330   reprZipStream(ret);
331   return ret.str();
332 }
333
334 /*!
335  * Changes number of tuples in the array. If the new number of tuples is smaller
336  * than the current number the array is truncated, otherwise the array is extended.
337  *  \param [in] nbOfTuples - new number of tuples. 
338  *  \throw If \a this is not allocated.
339  */
340 void DataArrayChar::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
341 {
342   checkAllocated();
343   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
344   declareAsNew();
345 }
346
347 /*!
348  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
349  * array to the new one.
350  *  \return DataArrayInt * - the new instance of DataArrayChar.
351  */
352 DataArrayInt *DataArrayChar::convertToIntArr() const throw(INTERP_KERNEL::Exception)
353 {
354   checkAllocated();
355   DataArrayInt *ret=DataArrayInt::New();
356   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
357   std::size_t nbOfVals=getNbOfElems();
358   const char *src=getConstPointer();
359   int *dest=ret->getPointer();
360   std::copy(src,src+nbOfVals,dest);
361   ret->copyStringInfoFrom(*this);
362   return ret;
363 }
364
365 /*!
366  * Permutes values of \a this array as required by \a old2New array. The values are
367  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
368  * the same as in \this one.
369  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
370  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
371  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
372  *     giving a new position for i-th old value.
373  */
374 void DataArrayChar::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
375 {
376   checkAllocated();
377   int nbTuples=getNumberOfTuples();
378   int nbOfCompo=getNumberOfComponents();
379   char *tmp=new char[nbTuples*nbOfCompo];
380   const char *iptr=getConstPointer();
381   for(int i=0;i<nbTuples;i++)
382     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*old2New[i]);
383   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
384   delete [] tmp;
385   declareAsNew();
386 }
387
388 /*!
389  * Permutes values of \a this array as required by \a new2Old array. The values are
390  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
391  * the same as in \this one.
392  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
393  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
394  *     giving a previous position of i-th new value.
395  */
396 void DataArrayChar::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
397 {
398   checkAllocated();
399   int nbTuples=getNumberOfTuples();
400   int nbOfCompo=getNumberOfComponents();
401   char *tmp=new char[nbTuples*nbOfCompo];
402   const char *iptr=getConstPointer();
403   for(int i=0;i<nbTuples;i++)
404     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),tmp+nbOfCompo*i);
405   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
406   delete [] tmp;
407   declareAsNew();
408 }
409
410 /*!
411  * Returns a copy of \a this array with values permuted as required by \a old2New array.
412  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
413  * Number of tuples in the result array remains the same as in \this one.
414  * If a permutation reduction is needed, renumberAndReduce() should be used.
415  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
416  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
417  *          giving a new position for i-th old value.
418  *  \return DataArrayChar * - the new instance of DataArrayChar that the caller
419  *          is to delete using decrRef() as it is no more needed.
420  *  \throw If \a this is not allocated.
421  */
422 DataArrayChar *DataArrayChar::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
423 {
424   checkAllocated();
425   int nbTuples=getNumberOfTuples();
426   int nbOfCompo=getNumberOfComponents();
427   MEDCouplingAutoRefCountObjectPtr<DataArrayChar> ret=buildEmptySpecializedDAChar();
428   ret->alloc(nbTuples,nbOfCompo);
429   ret->copyStringInfoFrom(*this);
430   const char *iptr=getConstPointer();
431   char *optr=ret->getPointer();
432   for(int i=0;i<nbTuples;i++)
433     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
434   ret->copyStringInfoFrom(*this);
435   return ret.retn();
436 }
437
438 /*!
439  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
440  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
441  * tuples in the result array remains the same as in \this one.
442  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
443  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
444  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
445  *     giving a previous position of i-th new value.
446  *  \return DataArrayChar * - the new instance of DataArrayChar that the caller
447  *          is to delete using decrRef() as it is no more needed.
448  */
449 DataArrayChar *DataArrayChar::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
450 {
451   checkAllocated();
452   int nbTuples=getNumberOfTuples();
453   int nbOfCompo=getNumberOfComponents();
454   MEDCouplingAutoRefCountObjectPtr<DataArrayChar> ret=buildEmptySpecializedDAChar();
455   ret->alloc(nbTuples,nbOfCompo);
456   ret->copyStringInfoFrom(*this);
457   const char *iptr=getConstPointer();
458   char *optr=ret->getPointer();
459   for(int i=0;i<nbTuples;i++)
460     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
461   ret->copyStringInfoFrom(*this);
462   return ret.retn();
463 }
464
465 /*!
466  * Returns a shorten and permuted copy of \a this array. The new DataArrayChar is
467  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
468  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
469  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
470  * \a old2New[ i ] is negative, is missing from the result array.
471  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
472  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
473  *     giving a new position for i-th old tuple and giving negative position for
474  *     for i-th old tuple that should be omitted.
475  *  \return DataArrayChar * - the new instance of DataArrayChar that the caller
476  *          is to delete using decrRef() as it is no more needed.
477  */
478 DataArrayChar *DataArrayChar::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
479 {
480   checkAllocated();
481   int nbTuples=getNumberOfTuples();
482   int nbOfCompo=getNumberOfComponents();
483   MEDCouplingAutoRefCountObjectPtr<DataArrayChar> ret=buildEmptySpecializedDAChar();
484   ret->alloc(newNbOfTuple,nbOfCompo);
485   const char *iptr=getConstPointer();
486   char *optr=ret->getPointer();
487   for(int i=0;i<nbTuples;i++)
488     {
489       int w=old2New[i];
490       if(w>=0)
491         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
492     }
493   ret->copyStringInfoFrom(*this);
494   return ret.retn();
495 }
496
497 /*!
498  * Returns a shorten and permuted copy of \a this array. The new DataArrayChar is
499  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
500  * \a new2OldBg array.
501  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
502  * This method is equivalent to renumberAndReduce() except that convention in input is
503  * \c new2old and \b not \c old2new.
504  * This method is equivalent to selectByTupleId() except that it prevents coping data
505  * from behind the end of \a this array.
506  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
507  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
508  *              tuple index in \a this array to fill the i-th tuple in the new array.
509  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
510  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
511  *              \a new2OldBg <= \a pi < \a new2OldEnd.
512  *  \return DataArrayChar * - the new instance of DataArrayChar that the caller
513  *          is to delete using decrRef() as it is no more needed.
514  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
515  */
516 DataArrayChar *DataArrayChar::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
517 {
518   checkAllocated();
519   MEDCouplingAutoRefCountObjectPtr<DataArrayChar> ret=buildEmptySpecializedDAChar();
520   int nbComp=getNumberOfComponents();
521   int oldNbOfTuples=getNumberOfTuples();
522   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
523   ret->copyStringInfoFrom(*this);
524   char *pt=ret->getPointer();
525   const char *srcPt=getConstPointer();
526   int i=0;
527   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
528     if(*w>=0 && *w<oldNbOfTuples)
529       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
530     else
531       throw INTERP_KERNEL::Exception("DataArrayChar::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
532   ret->copyStringInfoFrom(*this);
533   return ret.retn();
534 }
535
536 /*!
537  * Returns a shorten copy of \a this array. The new DataArrayChar contains every
538  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
539  * tuple. Indices of the selected tuples are the same as ones returned by the Python
540  * command \c range( \a bg, \a end2, \a step ).
541  * This method is equivalent to selectByTupleIdSafe() except that the input array is
542  * not constructed explicitly.
543  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
544  *  \param [in] bg - index of the first tuple to copy from \a this array.
545  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
546  *  \param [in] step - index increment to get index of the next tuple to copy.
547  *  \return DataArrayChar * - the new instance of DataArrayChar that the caller
548  *          is to delete using decrRef() as it is no more needed.
549  *  \throw If (\a end2 < \a bg) or (\a step <= 0).
550  *  \sa DataArrayChar::substr.
551  */
552 DataArrayChar *DataArrayChar::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
553 {
554   checkAllocated();
555   MEDCouplingAutoRefCountObjectPtr<DataArrayChar> ret=buildEmptySpecializedDAChar();
556   int nbComp=getNumberOfComponents();
557   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
558   ret->alloc(newNbOfTuples,nbComp);
559   char *pt=ret->getPointer();
560   const char *srcPt=getConstPointer()+bg*nbComp;
561   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
562     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
563   ret->copyStringInfoFrom(*this);
564   return ret.retn();
565 }
566
567 /*!
568  * Checks if all values in \a this array are equal to \a val.
569  *  \param [in] val - value to check equality of array values to.
570  *  \return bool - \a true if all values are \a val.
571  *  \throw If \a this is not allocated.
572  *  \throw If \a this->getNumberOfComponents() != 1
573  */
574 bool DataArrayChar::isUniform(char val) const throw(INTERP_KERNEL::Exception)
575 {
576   checkAllocated();
577   if(getNumberOfComponents()!=1)
578     throw INTERP_KERNEL::Exception("DataArrayChar::isUniform : must be applied on DataArrayChar with only one component, you can call 'rearrange' method before !");
579   int nbOfTuples=getNumberOfTuples();
580   const char *w=getConstPointer();
581   const char *end2=w+nbOfTuples;
582   for(;w!=end2;w++)
583     if(*w!=val)
584       return false;
585   return true;
586 }
587
588 /*!
589  * Changes the number of components within \a this array so that its raw data **does
590  * not** change, instead splitting this data into tuples changes.
591  *  \param [in] newNbOfComp - number of components for \a this array to have.
592  *  \throw If \a this is not allocated
593  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
594  *  \throw If \a newNbOfCompo is lower than 1.
595  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
596  *  \warning This method erases all (name and unit) component info set before!
597  */
598 void DataArrayChar::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
599 {
600   checkAllocated();
601   if(newNbOfCompo<1)
602     throw INTERP_KERNEL::Exception("DataArrayChar::rearrange : input newNbOfCompo must be > 0 !");
603   std::size_t nbOfElems=getNbOfElems();
604   if(nbOfElems%newNbOfCompo!=0)
605     throw INTERP_KERNEL::Exception("DataArrayChar::rearrange : nbOfElems%newNbOfCompo!=0 !");
606   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
607     throw INTERP_KERNEL::Exception("DataArrayChar::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
608   _info_on_compo.clear();
609   _info_on_compo.resize(newNbOfCompo);
610   declareAsNew();
611 }
612
613 /*!
614  * Returns a shorten copy of \a this array. The new DataArrayChar contains all
615  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
616  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
617  * This method is a specialization of selectByTupleId2().
618  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
619  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
620  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
621  *  \return DataArrayChar * - the new instance of DataArrayChar that the caller
622  *          is to delete using decrRef() as it is no more needed.
623  *  \throw If \a tupleIdBg < 0.
624  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
625     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
626  *  \sa DataArrayChar::selectByTupleId2
627  */
628 DataArrayChar *DataArrayChar::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
629 {
630   checkAllocated();
631   int nbt=getNumberOfTuples();
632   if(tupleIdBg<0)
633     throw INTERP_KERNEL::Exception("DataArrayChar::substr : The tupleIdBg parameter must be greater than 0 !");
634   if(tupleIdBg>nbt)
635     throw INTERP_KERNEL::Exception("DataArrayChar::substr : The tupleIdBg parameter is greater than number of tuples !");
636   int trueEnd=tupleIdEnd;
637   if(tupleIdEnd!=-1)
638     {
639       if(tupleIdEnd>nbt)
640         throw INTERP_KERNEL::Exception("DataArrayChar::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
641     }
642   else
643     trueEnd=nbt;
644   int nbComp=getNumberOfComponents();
645   MEDCouplingAutoRefCountObjectPtr<DataArrayChar> ret=buildEmptySpecializedDAChar();
646   ret->alloc(trueEnd-tupleIdBg,nbComp);
647   ret->copyStringInfoFrom(*this);
648   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
649   return ret.retn();
650 }
651
652 /*!
653  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
654  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
655  * is truncated to have \a newNbOfComp components, keeping first components. If \a
656  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
657  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
658  * components.  
659  *  \param [in] newNbOfComp - number of components for the new array to have.
660  *  \param [in] dftValue - value assigned to new values added to the new array.
661  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
662  *          is to delete using decrRef() as it is no more needed.
663  *  \throw If \a this is not allocated.
664  */
665 DataArrayChar *DataArrayChar::changeNbOfComponents(int newNbOfComp, char dftValue) const throw(INTERP_KERNEL::Exception)
666 {
667   checkAllocated();
668   MEDCouplingAutoRefCountObjectPtr<DataArrayChar> ret=buildEmptySpecializedDAChar();
669   ret->alloc(getNumberOfTuples(),newNbOfComp);
670   const char *oldc=getConstPointer();
671   char *nc=ret->getPointer();
672   int nbOfTuples=getNumberOfTuples();
673   int oldNbOfComp=getNumberOfComponents();
674   int dim=std::min(oldNbOfComp,newNbOfComp);
675   for(int i=0;i<nbOfTuples;i++)
676     {
677       int j=0;
678       for(;j<dim;j++)
679         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
680       for(;j<newNbOfComp;j++)
681         nc[newNbOfComp*i+j]=dftValue;
682     }
683   ret->setName(getName().c_str());
684   for(int i=0;i<dim;i++)
685     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
686   ret->setName(getName().c_str());
687   return ret.retn();
688 }
689
690 /*!
691  * Returns a copy of \a this array composed of selected components.
692  * The new DataArrayChar has the same number of tuples but includes components
693  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
694  * can be either less, same or more than \a this->getNbOfElems().
695  *  \param [in] compoIds - sequence of zero based indices of components to include
696  *              into the new array.
697  *  \return DataArrayChar * - the new instance of DataArrayChar that the caller
698  *          is to delete using decrRef() as it is no more needed.
699  *  \throw If \a this is not allocated.
700  *  \throw If a component index (\a i) is not valid: 
701  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
702  *
703  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
704  */
705 DataArray *DataArrayChar::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
706 {
707   checkAllocated();
708   MEDCouplingAutoRefCountObjectPtr<DataArrayChar> ret(buildEmptySpecializedDAChar());
709   int newNbOfCompo=(int)compoIds.size();
710   int oldNbOfCompo=getNumberOfComponents();
711   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
712     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
713   int nbOfTuples=getNumberOfTuples();
714   ret->alloc(nbOfTuples,newNbOfCompo);
715   ret->copyPartOfStringInfoFrom(*this,compoIds);
716   const char *oldc=getConstPointer();
717   char *nc=ret->getPointer();
718   for(int i=0;i<nbOfTuples;i++)
719     for(int j=0;j<newNbOfCompo;j++,nc++)
720       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
721   return ret.retn();
722 }
723
724 /*!
725  * Appends components of another array to components of \a this one, tuple by tuple.
726  * So that the number of tuples of \a this array remains the same and the number of 
727  * components increases.
728  *  \param [in] other - the DataArrayChar to append to \a this one.
729  *  \throw If \a this is not allocated.
730  *  \throw If \a this and \a other arrays have different number of tuples.
731  *
732  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
733  *
734  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
735  */
736 void DataArrayChar::meldWith(const DataArrayChar *other) throw(INTERP_KERNEL::Exception)
737 {
738   if(!other)
739     throw INTERP_KERNEL::Exception("DataArrayChar::meldWith : DataArrayChar pointer in input is NULL !");
740   checkAllocated();
741   other->checkAllocated();
742   int nbOfTuples=getNumberOfTuples();
743   if(nbOfTuples!=other->getNumberOfTuples())
744     throw INTERP_KERNEL::Exception("DataArrayChar::meldWith : mismatch of number of tuples !");
745   int nbOfComp1=getNumberOfComponents();
746   int nbOfComp2=other->getNumberOfComponents();
747   char *newArr=(char *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(char));
748   char *w=newArr;
749   const char *inp1=getConstPointer();
750   const char *inp2=other->getConstPointer();
751   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
752     {
753       w=std::copy(inp1,inp1+nbOfComp1,w);
754       w=std::copy(inp2,inp2+nbOfComp2,w);
755     }
756   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
757   std::vector<int> compIds(nbOfComp2);
758   for(int i=0;i<nbOfComp2;i++)
759     compIds[i]=nbOfComp1+i;
760   copyPartOfStringInfoFrom2(compIds,*other);
761 }
762
763 /*!
764  * Copy all values from another DataArrayChar into specified tuples and components
765  * of \a this array. Textual data is not copied.
766  * The tree parameters defining set of indices of tuples and components are similar to
767  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
768  *  \param [in] a - the array to copy values from.
769  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
770  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
771  *              are located.
772  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
773  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
774  *  \param [in] endComp - index of the component before which the components to assign
775  *              to are located.
776  *  \param [in] stepComp - index increment to get index of the next component to assign to.
777  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
778  *              must be equal to the number of columns to assign to, else an
779  *              exception is thrown; if \a false, then it is only required that \a
780  *              a->getNbOfElems() equals to number of values to assign to (this condition
781  *              must be respected even if \a strictCompoCompare is \a true). The number of 
782  *              values to assign to is given by following Python expression:
783  *              \a nbTargetValues = 
784  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
785  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
786  *  \throw If \a a is NULL.
787  *  \throw If \a a is not allocated.
788  *  \throw If \a this is not allocated.
789  *  \throw If parameters specifying tuples and components to assign to do not give a
790  *            non-empty range of increasing indices.
791  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
792  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
793  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
794  *
795  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
796  */
797 void DataArrayChar::setPartOfValues1(const DataArrayChar *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
798 {
799   if(!a)
800     throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValues1 : DataArrayChar pointer in input is NULL !");
801   const char msg[]="DataArrayChar::setPartOfValues1";
802   checkAllocated();
803   a->checkAllocated();
804   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
805   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
806   int nbComp=getNumberOfComponents();
807   int nbOfTuples=getNumberOfTuples();
808   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
809   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
810   bool assignTech=true;
811   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
812     {
813       if(strictCompoCompare)
814         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
815     }
816   else
817     {
818       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
819       assignTech=false;
820     }
821   char *pt=getPointer()+bgTuples*nbComp+bgComp;
822   const char *srcPt=a->getConstPointer();
823   if(assignTech)
824     {
825       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
826         for(int j=0;j<newNbOfComp;j++,srcPt++)
827           pt[j*stepComp]=*srcPt;
828     }
829   else
830     {
831       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
832         {
833           const char *srcPt2=srcPt;
834           for(int j=0;j<newNbOfComp;j++,srcPt2++)
835             pt[j*stepComp]=*srcPt2;
836         }
837     }
838 }
839
840 /*!
841  * Assign a given value to values at specified tuples and components of \a this array.
842  * The tree parameters defining set of indices of tuples and components are similar to
843  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
844  *  \param [in] a - the value to assign.
845  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
846  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
847  *              are located.
848  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
849  *  \param [in] bgComp - index of the first component of \a this array to assign to.
850  *  \param [in] endComp - index of the component before which the components to assign
851  *              to are located.
852  *  \param [in] stepComp - index increment to get index of the next component to assign to.
853  *  \throw If \a this is not allocated.
854  *  \throw If parameters specifying tuples and components to assign to, do not give a
855  *            non-empty range of increasing indices or indices are out of a valid range
856  *            for \this array.
857  *
858  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
859  */
860 void DataArrayChar::setPartOfValuesSimple1(char a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
861 {
862   const char msg[]="DataArrayChar::setPartOfValuesSimple1";
863   checkAllocated();
864   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
865   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
866   int nbComp=getNumberOfComponents();
867   int nbOfTuples=getNumberOfTuples();
868   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
869   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
870   char *pt=getPointer()+bgTuples*nbComp+bgComp;
871   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
872     for(int j=0;j<newNbOfComp;j++)
873       pt[j*stepComp]=a;
874 }
875
876
877 /*!
878  * Copy all values from another DataArrayChar (\a a) into specified tuples and 
879  * components of \a this array. Textual data is not copied.
880  * The tuples and components to assign to are defined by C arrays of indices.
881  * There are two *modes of usage*:
882  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
883  *   of \a a is assigned to its own location within \a this array. 
884  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
885  *   components of every specified tuple of \a this array. In this mode it is required
886  *   that \a a->getNumberOfComponents() equals to the number of specified components.
887  * 
888  *  \param [in] a - the array to copy values from.
889  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
890  *              assign values of \a a to.
891  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
892  *              pointer to a tuple index <em>(pi)</em> varies as this: 
893  *              \a bgTuples <= \a pi < \a endTuples.
894  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
895  *              assign values of \a a to.
896  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
897  *              pointer to a component index <em>(pi)</em> varies as this: 
898  *              \a bgComp <= \a pi < \a endComp.
899  *  \param [in] strictCompoCompare - this parameter is checked only if the
900  *               *mode of usage* is the first; if it is \a true (default), 
901  *               then \a a->getNumberOfComponents() must be equal 
902  *               to the number of specified columns, else this is not required.
903  *  \throw If \a a is NULL.
904  *  \throw If \a a is not allocated.
905  *  \throw If \a this is not allocated.
906  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
907  *         out of a valid range for \a this array.
908  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
909  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
910  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
911  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
912  *
913  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
914  */
915 void DataArrayChar::setPartOfValues2(const DataArrayChar *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
916 {
917   if(!a)
918     throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValues2 : DataArrayChar pointer in input is NULL !");
919   const char msg[]="DataArrayChar::setPartOfValues2";
920   checkAllocated();
921   a->checkAllocated();
922   int nbComp=getNumberOfComponents();
923   int nbOfTuples=getNumberOfTuples();
924   for(const int *z=bgComp;z!=endComp;z++)
925     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
926   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
927   int newNbOfComp=(int)std::distance(bgComp,endComp);
928   bool assignTech=true;
929   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
930     {
931       if(strictCompoCompare)
932         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
933     }
934   else
935     {
936       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
937       assignTech=false;
938     }
939   char *pt=getPointer();
940   const char *srcPt=a->getConstPointer();
941   if(assignTech)
942     {    
943       for(const int *w=bgTuples;w!=endTuples;w++)
944         {
945           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
946           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
947             {    
948               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
949             }
950         }
951     }
952   else
953     {
954       for(const int *w=bgTuples;w!=endTuples;w++)
955         {
956           const char *srcPt2=srcPt;
957           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
958           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
959             {    
960               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
961             }
962         }
963     }
964 }
965
966 /*!
967  * Assign a given value to values at specified tuples and components of \a this array.
968  * The tuples and components to assign to are defined by C arrays of indices.
969  *  \param [in] a - the value to assign.
970  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
971  *              assign \a a to.
972  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
973  *              pointer to a tuple index (\a pi) varies as this: 
974  *              \a bgTuples <= \a pi < \a endTuples.
975  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
976  *              assign \a a to.
977  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
978  *              pointer to a component index (\a pi) varies as this: 
979  *              \a bgComp <= \a pi < \a endComp.
980  *  \throw If \a this is not allocated.
981  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
982  *         out of a valid range for \a this array.
983  *
984  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
985  */
986 void DataArrayChar::setPartOfValuesSimple2(char a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
987 {
988   checkAllocated();
989   int nbComp=getNumberOfComponents();
990   int nbOfTuples=getNumberOfTuples();
991   for(const int *z=bgComp;z!=endComp;z++)
992     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
993   char *pt=getPointer();
994   for(const int *w=bgTuples;w!=endTuples;w++)
995     for(const int *z=bgComp;z!=endComp;z++)
996       {
997         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
998         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
999       }
1000 }
1001
1002 /*!
1003  * Copy all values from another DataArrayChar (\a a) into specified tuples and 
1004  * components of \a this array. Textual data is not copied.
1005  * The tuples to assign to are defined by a C array of indices.
1006  * The components to assign to are defined by three values similar to parameters of
1007  * the Python function \c range(\c start,\c stop,\c step).
1008  * There are two *modes of usage*:
1009  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
1010  *   of \a a is assigned to its own location within \a this array. 
1011  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
1012  *   components of every specified tuple of \a this array. In this mode it is required
1013  *   that \a a->getNumberOfComponents() equals to the number of specified components.
1014  *
1015  *  \param [in] a - the array to copy values from.
1016  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
1017  *              assign values of \a a to.
1018  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
1019  *              pointer to a tuple index <em>(pi)</em> varies as this: 
1020  *              \a bgTuples <= \a pi < \a endTuples.
1021  *  \param [in] bgComp - index of the first component of \a this array to assign to.
1022  *  \param [in] endComp - index of the component before which the components to assign
1023  *              to are located.
1024  *  \param [in] stepComp - index increment to get index of the next component to assign to.
1025  *  \param [in] strictCompoCompare - this parameter is checked only in the first
1026  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
1027  *               then \a a->getNumberOfComponents() must be equal 
1028  *               to the number of specified columns, else this is not required.
1029  *  \throw If \a a is NULL.
1030  *  \throw If \a a is not allocated.
1031  *  \throw If \a this is not allocated.
1032  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
1033  *         \a this array.
1034  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
1035  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
1036  *         defined by <em>(bgComp,endComp,stepComp)</em>.
1037  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
1038  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
1039  *         defined by <em>(bgComp,endComp,stepComp)</em>.
1040  *  \throw If parameters specifying components to assign to, do not give a
1041  *            non-empty range of increasing indices or indices are out of a valid range
1042  *            for \this array.
1043  *
1044  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
1045  */
1046 void DataArrayChar::setPartOfValues3(const DataArrayChar *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
1047 {
1048   if(!a)
1049     throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValues3 : DataArrayChar pointer in input is NULL !");
1050   const char msg[]="DataArrayChar::setPartOfValues3";
1051   checkAllocated();
1052   a->checkAllocated();
1053   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
1054   int nbComp=getNumberOfComponents();
1055   int nbOfTuples=getNumberOfTuples();
1056   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
1057   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
1058   bool assignTech=true;
1059   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
1060     {
1061       if(strictCompoCompare)
1062         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
1063     }
1064   else
1065     {
1066       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
1067       assignTech=false;
1068     }
1069   char *pt=getPointer()+bgComp;
1070   const char *srcPt=a->getConstPointer();
1071   if(assignTech)
1072     {
1073       for(const int *w=bgTuples;w!=endTuples;w++)
1074         for(int j=0;j<newNbOfComp;j++,srcPt++)
1075           {
1076             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1077             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
1078           }
1079     }
1080   else
1081     {
1082       for(const int *w=bgTuples;w!=endTuples;w++)
1083         {
1084           const char *srcPt2=srcPt;
1085           for(int j=0;j<newNbOfComp;j++,srcPt2++)
1086             {
1087               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1088               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
1089             }
1090         }
1091     }
1092 }
1093
1094 /*!
1095  * Assign a given value to values at specified tuples and components of \a this array.
1096  * The tuples to assign to are defined by a C array of indices.
1097  * The components to assign to are defined by three values similar to parameters of
1098  * the Python function \c range(\c start,\c stop,\c step).
1099  *  \param [in] a - the value to assign.
1100  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
1101  *              assign \a a to.
1102  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
1103  *              pointer to a tuple index <em>(pi)</em> varies as this: 
1104  *              \a bgTuples <= \a pi < \a endTuples.
1105  *  \param [in] bgComp - index of the first component of \a this array to assign to.
1106  *  \param [in] endComp - index of the component before which the components to assign
1107  *              to are located.
1108  *  \param [in] stepComp - index increment to get index of the next component to assign to.
1109  *  \throw If \a this is not allocated.
1110  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
1111  *         \a this array.
1112  *  \throw If parameters specifying components to assign to, do not give a
1113  *            non-empty range of increasing indices or indices are out of a valid range
1114  *            for \this array.
1115  *
1116  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
1117  */
1118 void DataArrayChar::setPartOfValuesSimple3(char a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
1119 {
1120   const char msg[]="DataArrayChar::setPartOfValuesSimple3";
1121   checkAllocated();
1122   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
1123   int nbComp=getNumberOfComponents();
1124   int nbOfTuples=getNumberOfTuples();
1125   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
1126   char *pt=getPointer()+bgComp;
1127   for(const int *w=bgTuples;w!=endTuples;w++)
1128     for(int j=0;j<newNbOfComp;j++)
1129       {
1130         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1131         pt[(*w)*nbComp+j*stepComp]=a;
1132       }
1133 }
1134
1135 void DataArrayChar::setPartOfValues4(const DataArrayChar *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
1136 {
1137   if(!a)
1138     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
1139   const char msg[]="DataArrayInt::setPartOfValues4";
1140   checkAllocated();
1141   a->checkAllocated();
1142   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
1143   int newNbOfComp=(int)std::distance(bgComp,endComp);
1144   int nbComp=getNumberOfComponents();
1145   for(const int *z=bgComp;z!=endComp;z++)
1146     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
1147   int nbOfTuples=getNumberOfTuples();
1148   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
1149   bool assignTech=true;
1150   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
1151     {
1152       if(strictCompoCompare)
1153         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
1154     }
1155   else
1156     {
1157       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
1158       assignTech=false;
1159     }
1160   const char *srcPt=a->getConstPointer();
1161   char *pt=getPointer()+bgTuples*nbComp;
1162   if(assignTech)
1163     {
1164       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1165         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
1166           pt[*z]=*srcPt;
1167     }
1168   else
1169     {
1170       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1171         {
1172           const char *srcPt2=srcPt;
1173           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
1174             pt[*z]=*srcPt2;
1175         }
1176     }
1177 }
1178
1179 void DataArrayChar::setPartOfValuesSimple4(char a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
1180 {
1181   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
1182   checkAllocated();
1183   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
1184   int nbComp=getNumberOfComponents();
1185   for(const int *z=bgComp;z!=endComp;z++)
1186     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
1187   int nbOfTuples=getNumberOfTuples();
1188   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
1189   char *pt=getPointer()+bgTuples*nbComp;
1190   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1191     for(const int *z=bgComp;z!=endComp;z++)
1192       pt[*z]=a;
1193 }
1194
1195 /*!
1196  * Copy some tuples from another DataArrayChar into specified tuples
1197  * of \a this array. Textual data is not copied. Both arrays must have equal number of
1198  * components.
1199  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayChar.
1200  * All components of selected tuples are copied.
1201  *  \param [in] a - the array to copy values from.
1202  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
1203  *              target tuples of \a this. \a tuplesSelec has two components, and the
1204  *              first component specifies index of the source tuple and the second
1205  *              one specifies index of the target tuple.
1206  *  \throw If \a this is not allocated.
1207  *  \throw If \a a is NULL.
1208  *  \throw If \a a is not allocated.
1209  *  \throw If \a tuplesSelec is NULL.
1210  *  \throw If \a tuplesSelec is not allocated.
1211  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
1212  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
1213  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
1214  *         the corresponding (\a this or \a a) array.
1215  */
1216 void DataArrayChar::setPartOfValuesAdv(const DataArrayChar *a, const DataArrayChar *tuplesSelec) throw(INTERP_KERNEL::Exception)
1217 {
1218   if(!a || !tuplesSelec)
1219     throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValuesAdv : DataArrayChar pointer in input is NULL !");
1220   checkAllocated();
1221   a->checkAllocated();
1222   tuplesSelec->checkAllocated();
1223   int nbOfComp=getNumberOfComponents();
1224   if(nbOfComp!=a->getNumberOfComponents())
1225     throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValuesAdv : This and a do not have the same number of components !");
1226   if(tuplesSelec->getNumberOfComponents()!=2)
1227     throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayChar instance with exactly 2 components !");
1228   int thisNt=getNumberOfTuples();
1229   int aNt=a->getNumberOfTuples();
1230   char *valsToSet=getPointer();
1231   const char *valsSrc=a->getConstPointer();
1232   for(const char *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
1233     {
1234       if(tuple[1]>=0 && tuple[1]<aNt)
1235         {
1236           if(tuple[0]>=0 && tuple[0]<thisNt)
1237             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
1238           else
1239             {
1240               std::ostringstream oss; oss << "DataArrayChar::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
1241               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
1242               throw INTERP_KERNEL::Exception(oss.str().c_str());
1243             }
1244         }
1245       else
1246         {
1247           std::ostringstream oss; oss << "DataArrayChar::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
1248           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
1249           throw INTERP_KERNEL::Exception(oss.str().c_str());
1250         }
1251     }
1252 }
1253
1254 /*!
1255  * Copy some tuples from another DataArrayChar (\a a) into contiguous tuples
1256  * of \a this array. Textual data is not copied. Both arrays must have equal number of
1257  * components.
1258  * The tuples to assign to are defined by index of the first tuple, and
1259  * their number is defined by \a tuplesSelec->getNumberOfTuples().
1260  * The tuples to copy are defined by values of a DataArrayChar.
1261  * All components of selected tuples are copied.
1262  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
1263  *              values to.
1264  *  \param [in] a - the array to copy values from.
1265  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
1266  *  \throw If \a this is not allocated.
1267  *  \throw If \a a is NULL.
1268  *  \throw If \a a is not allocated.
1269  *  \throw If \a tuplesSelec is NULL.
1270  *  \throw If \a tuplesSelec is not allocated.
1271  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
1272  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
1273  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
1274  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
1275  *         \a a array.
1276  */
1277 void DataArrayChar::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
1278 {
1279   if(!aBase || !tuplesSelec)
1280     throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : input DataArray is NULL !");
1281   const DataArrayChar *a=dynamic_cast<const DataArrayChar *>(aBase);
1282   if(!a)
1283     throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayChar !");
1284   checkAllocated();
1285   a->checkAllocated();
1286   tuplesSelec->checkAllocated();
1287   int nbOfComp=getNumberOfComponents();
1288   if(nbOfComp!=a->getNumberOfComponents())
1289     throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : This and a do not have the same number of components !");
1290   if(tuplesSelec->getNumberOfComponents()!=1)
1291     throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayChar instance with exactly 1 component !");
1292   int thisNt=getNumberOfTuples();
1293   int aNt=a->getNumberOfTuples();
1294   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
1295   char *valsToSet=getPointer()+tupleIdStart*nbOfComp;
1296   if(tupleIdStart+nbOfTupleToWrite>thisNt)
1297     throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : invalid number range of values to write !");
1298   const char *valsSrc=a->getConstPointer();
1299   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
1300     {
1301       if(*tuple>=0 && *tuple<aNt)
1302         {
1303           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
1304         }
1305       else
1306         {
1307           std::ostringstream oss; oss << "DataArrayChar::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
1308           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
1309           throw INTERP_KERNEL::Exception(oss.str().c_str());
1310         }
1311     }
1312 }
1313
1314 /*!
1315  * Copy some tuples from another DataArrayChar (\a a) into contiguous tuples
1316  * of \a this array. Textual data is not copied. Both arrays must have equal number of
1317  * components.
1318  * The tuples to copy are defined by three values similar to parameters of
1319  * the Python function \c range(\c start,\c stop,\c step).
1320  * The tuples to assign to are defined by index of the first tuple, and
1321  * their number is defined by number of tuples to copy.
1322  * All components of selected tuples are copied.
1323  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
1324  *              values to.
1325  *  \param [in] a - the array to copy values from.
1326  *  \param [in] bg - index of the first tuple to copy of the array \a a.
1327  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
1328  *              are located.
1329  *  \param [in] step - index increment to get index of the next tuple to copy.
1330  *  \throw If \a this is not allocated.
1331  *  \throw If \a a is NULL.
1332  *  \throw If \a a is not allocated.
1333  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
1334  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
1335  *  \throw If parameters specifying tuples to copy, do not give a
1336  *            non-empty range of increasing indices or indices are out of a valid range
1337  *            for the array \a a.
1338  */
1339 void DataArrayChar::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
1340 {
1341   if(!aBase)
1342     throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues2 : input DataArray is NULL !");
1343   const DataArrayChar *a=dynamic_cast<const DataArrayChar *>(aBase);
1344   if(!a)
1345     throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayChar !");
1346   checkAllocated();
1347   a->checkAllocated();
1348   int nbOfComp=getNumberOfComponents();
1349   const char msg[]="DataArrayChar::setContigPartOfSelectedValues2";
1350   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
1351   if(nbOfComp!=a->getNumberOfComponents())
1352     throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
1353   int thisNt=getNumberOfTuples();
1354   int aNt=a->getNumberOfTuples();
1355   char *valsToSet=getPointer()+tupleIdStart*nbOfComp;
1356   if(tupleIdStart+nbOfTupleToWrite>thisNt)
1357     throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues2 : invalid number range of values to write !");
1358   if(end2>aNt)
1359     throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues2 : invalid range of values to read !");
1360   const char *valsSrc=a->getConstPointer()+bg*nbOfComp;
1361   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
1362     {
1363       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
1364     }
1365 }
1366
1367 /*!
1368  * Returns a shorten copy of \a this array. The new DataArrayChar contains ranges
1369  * of tuples specified by \a ranges parameter.
1370  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1371  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1372  *              of tuples in [\c begin,\c end) format.
1373  *  \return DataArrayChar * - the new instance of DataArrayChar that the caller
1374  *          is to delete using decrRef() as it is no more needed.
1375  *  \throw If \a end < \a begin.
1376  *  \throw If \a end > \a this->getNumberOfTuples().
1377  *  \throw If \a this is not allocated.
1378  */
1379 DataArray *DataArrayChar::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
1380 {
1381   checkAllocated();
1382   int nbOfComp=getNumberOfComponents();
1383   int nbOfTuplesThis=getNumberOfTuples();
1384   if(ranges.empty())
1385     {
1386       MEDCouplingAutoRefCountObjectPtr<DataArrayChar> ret=buildEmptySpecializedDAChar();
1387       ret->alloc(0,nbOfComp);
1388       ret->copyStringInfoFrom(*this);
1389       return ret.retn();
1390     }
1391   int ref=ranges.front().first;
1392   int nbOfTuples=0;
1393   bool isIncreasing=true;
1394   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1395     {
1396       if((*it).first<=(*it).second)
1397         {
1398           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1399             {
1400               nbOfTuples+=(*it).second-(*it).first;
1401               if(isIncreasing)
1402                 isIncreasing=ref<=(*it).first;
1403               ref=(*it).second;
1404             }
1405           else
1406             {
1407               std::ostringstream oss; oss << "DataArrayChar::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1408               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1409               throw INTERP_KERNEL::Exception(oss.str().c_str());
1410             }
1411         }
1412       else
1413         {
1414           std::ostringstream oss; oss << "DataArrayChar::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1415           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1416           throw INTERP_KERNEL::Exception(oss.str().c_str());
1417         }
1418     }
1419   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1420     return deepCpy();
1421   MEDCouplingAutoRefCountObjectPtr<DataArrayChar> ret=buildEmptySpecializedDAChar();
1422   ret->alloc(nbOfTuples,nbOfComp);
1423   ret->copyStringInfoFrom(*this);
1424   const char *src=getConstPointer();
1425   char *work=ret->getPointer();
1426   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1427     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1428   return ret.retn();
1429 }
1430
1431 /*!
1432  * Returns a value located at specified tuple and component.
1433  * This method is equivalent to DataArrayChar::getIJ() except that validity of
1434  * parameters is checked. So this method is safe but expensive if used to go through
1435  * all values of \a this.
1436  *  \param [in] tupleId - index of tuple of interest.
1437  *  \param [in] compoId - index of component of interest.
1438  *  \return double - value located by \a tupleId and \a compoId.
1439  *  \throw If \a this is not allocated.
1440  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
1441  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
1442  */
1443 char DataArrayChar::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
1444 {
1445   checkAllocated();
1446   if(tupleId<0 || tupleId>=getNumberOfTuples())
1447     {
1448       std::ostringstream oss; oss << "DataArrayChar::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
1449       throw INTERP_KERNEL::Exception(oss.str().c_str());
1450     }
1451   if(compoId<0 || compoId>=getNumberOfComponents())
1452     {
1453       std::ostringstream oss; oss << "DataArrayChar::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
1454       throw INTERP_KERNEL::Exception(oss.str().c_str());
1455     }
1456   return _mem[tupleId*_info_on_compo.size()+compoId];
1457 }
1458
1459 /*!
1460  * Returns the last value of \a this. 
1461  *  \return double - the last value of \a this array.
1462  *  \throw If \a this is not allocated.
1463  *  \throw If \a this->getNumberOfComponents() != 1.
1464  *  \throw If \a this->getNumberOfTuples() < 1.
1465  */
1466 char DataArrayChar::back() const throw(INTERP_KERNEL::Exception)
1467 {
1468   checkAllocated();
1469   if(getNumberOfComponents()!=1)
1470     throw INTERP_KERNEL::Exception("DataArrayChar::back : number of components not equal to one !");
1471   int nbOfTuples=getNumberOfTuples();
1472   if(nbOfTuples<1)
1473     throw INTERP_KERNEL::Exception("DataArrayChar::back : number of tuples must be >= 1 !");
1474   return *(getConstPointer()+nbOfTuples-1);
1475 }
1476
1477 /*!
1478  * Creates a new DataArrayChar containing IDs (indices) of tuples holding value equal to a
1479  * given one.
1480  *  \param [in] val - the value to find within \a this.
1481  *  \return DataArrayChar * - a new instance of DataArrayChar. The caller is to delete this
1482  *          array using decrRef() as it is no more needed.
1483  *  \throw If \a this is not allocated.
1484  *  \throw If \a this->getNumberOfComponents() != 1.
1485  */
1486 DataArrayInt *DataArrayChar::getIdsEqual(char val) const throw(INTERP_KERNEL::Exception)
1487 {
1488   checkAllocated();
1489   if(getNumberOfComponents()!=1)
1490     throw INTERP_KERNEL::Exception("DataArrayChar::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
1491   const char *cptr=getConstPointer();
1492   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
1493   int nbOfTuples=getNumberOfTuples();
1494   for(int i=0;i<nbOfTuples;i++,cptr++)
1495     if(*cptr==val)
1496       ret->pushBackSilent(i);
1497   return ret.retn();
1498 }
1499
1500 /*!
1501  * Creates a new DataArrayChar containing IDs (indices) of tuples holding value \b not
1502  * equal to a given one. 
1503  *  \param [in] val - the value to ignore within \a this.
1504  *  \return DataArrayChar * - a new instance of DataArrayChar. The caller is to delete this
1505  *          array using decrRef() as it is no more needed.
1506  *  \throw If \a this is not allocated.
1507  *  \throw If \a this->getNumberOfComponents() != 1.
1508  */
1509 DataArrayInt *DataArrayChar::getIdsNotEqual(char val) const throw(INTERP_KERNEL::Exception)
1510 {
1511   checkAllocated();
1512   if(getNumberOfComponents()!=1)
1513     throw INTERP_KERNEL::Exception("DataArrayChar::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
1514   const char *cptr=getConstPointer();
1515   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
1516   int nbOfTuples=getNumberOfTuples();
1517   for(int i=0;i<nbOfTuples;i++,cptr++)
1518     if(*cptr!=val)
1519       ret->pushBackSilent(i);
1520   return ret.retn();
1521 }
1522
1523 /*!
1524  * This method searches the sequence specified in input parameter \b vals in \b this.
1525  * This works only for DataArrayChar having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
1526  * This method differs from DataArrayChar::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayChar::locateTuple.
1527  * \sa DataArrayChar::locateTuple
1528  */
1529 int DataArrayChar::search(const std::vector<char>& vals) const throw(INTERP_KERNEL::Exception)
1530 {
1531   checkAllocated();
1532   int nbOfCompo=getNumberOfComponents();
1533   if(nbOfCompo!=1)
1534     throw INTERP_KERNEL::Exception("DataArrayChar::search : works only for DataArrayChar instance with one component !");
1535   const char *cptr=getConstPointer();
1536   std::size_t nbOfVals=getNbOfElems();
1537   const char *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
1538   if(loc!=cptr+nbOfVals)
1539     return std::distance(cptr,loc);
1540   return -1;
1541 }
1542
1543 /*!
1544  * This method is an extension of DataArrayChar::locateValue method because this method works for DataArrayChar with
1545  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
1546  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
1547  * If any the tuple id is returned. If not -1 is returned.
1548  * 
1549  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
1550  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
1551  *
1552  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
1553  * \sa DataArrayChar::search.
1554  */
1555 int DataArrayChar::locateTuple(const std::vector<char>& tupl) const throw(INTERP_KERNEL::Exception)
1556 {
1557   checkAllocated();
1558   int nbOfCompo=getNumberOfComponents();
1559   if(nbOfCompo==0)
1560     throw INTERP_KERNEL::Exception("DataArrayChar::locateTuple : 0 components in 'this' !");
1561   if(nbOfCompo!=(int)tupl.size())
1562     {
1563       std::ostringstream oss; oss << "DataArrayChar::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
1564       throw INTERP_KERNEL::Exception(oss.str().c_str());
1565     }
1566   const char *cptr=getConstPointer();
1567   std::size_t nbOfVals=getNbOfElems();
1568   for(const char *work=cptr;work!=cptr+nbOfVals;)
1569     {
1570       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
1571       if(work!=cptr+nbOfVals)
1572         {
1573           if(std::distance(cptr,work)%nbOfCompo!=0)
1574             work++;
1575           else
1576             return std::distance(cptr,work)/nbOfCompo;
1577         }
1578     }
1579   return -1;
1580 }
1581
1582 /*!
1583  * This method is an extension of DataArrayChar::presenceOfValue method because this method works for DataArrayChar with
1584  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
1585  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
1586  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
1587  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
1588  * \sa DataArrayChar::locateTuple
1589  */
1590 bool DataArrayChar::presenceOfTuple(const std::vector<char>& tupl) const throw(INTERP_KERNEL::Exception)
1591 {
1592   return locateTuple(tupl)!=-1;
1593 }
1594
1595 /*!
1596  * Returns \a true if a given value is present within \a this one-dimensional array.
1597  *  \param [in] value - the value to find within \a this array.
1598  *  \return bool - \a true in case if \a value is present within \a this array.
1599  *  \throw If \a this is not allocated.
1600  *  \throw If \a this->getNumberOfComponents() != 1.
1601  *  \sa locateValue()
1602  */
1603 bool DataArrayChar::presenceOfValue(char value) const throw(INTERP_KERNEL::Exception)
1604 {
1605   return locateValue(value)!=-1;
1606 }
1607
1608 /*!
1609  * This method expects to be called when number of components of this is equal to one.
1610  * This method returns true if it exists a tuple so that the value is contained in \b vals.
1611  * If not any tuple contains one of the values contained in 'vals' false is returned.
1612  * \sa DataArrayChar::locateValue
1613  */
1614 bool DataArrayChar::presenceOfValue(const std::vector<char>& vals) const throw(INTERP_KERNEL::Exception)
1615 {
1616   return locateValue(vals)!=-1;
1617 }
1618
1619 /*!
1620  * This method expects to be called when number of components of this is equal to one.
1621  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
1622  * If not any tuple contains \b value -1 is returned.
1623  * \sa DataArrayChar::presenceOfValue
1624  */
1625 int DataArrayChar::locateValue(char value) const throw(INTERP_KERNEL::Exception)
1626 {
1627   checkAllocated();
1628   if(getNumberOfComponents()!=1)
1629     throw INTERP_KERNEL::Exception("DataArrayChar::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
1630   const char *cptr=getConstPointer();
1631   int nbOfTuples=getNumberOfTuples();
1632   const char *ret=std::find(cptr,cptr+nbOfTuples,value);
1633   if(ret!=cptr+nbOfTuples)
1634     return std::distance(cptr,ret);
1635   return -1;
1636 }
1637
1638 /*!
1639  * This method expects to be called when number of components of this is equal to one.
1640  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
1641  * If not any tuple contains one of the values contained in 'vals' false is returned.
1642  * \sa DataArrayChar::presenceOfValue
1643  */
1644 int DataArrayChar::locateValue(const std::vector<char>& vals) const throw(INTERP_KERNEL::Exception)
1645 {
1646   checkAllocated();
1647   if(getNumberOfComponents()!=1)
1648     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
1649   std::set<char> vals2(vals.begin(),vals.end());
1650   const char *cptr=getConstPointer();
1651   int nbOfTuples=getNumberOfTuples();
1652   for(const char *w=cptr;w!=cptr+nbOfTuples;w++)
1653     if(vals2.find(*w)!=vals2.end())
1654       return std::distance(cptr,w);
1655   return -1;
1656 }
1657
1658 /*!
1659  * Returns the maximal value and its location within \a this one-dimensional array.
1660  *  \param [out] tupleId - index of the tuple holding the maximal value.
1661  *  \return double - the maximal value among all values of \a this array.
1662  *  \throw If \a this->getNumberOfComponents() != 1
1663  *  \throw If \a this->getNumberOfTuples() < 1
1664  */
1665 char DataArrayChar::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
1666 {
1667   checkAllocated();
1668   if(getNumberOfComponents()!=1)
1669     throw INTERP_KERNEL::Exception("DataArrayChar::getMaxValue : must be applied on DataArrayChar with only one component !");
1670   int nbOfTuples=getNumberOfTuples();
1671   if(nbOfTuples<=0)
1672     throw INTERP_KERNEL::Exception("DataArrayChar::getMaxValue : array exists but number of tuples must be > 0 !");
1673   const char *vals=getConstPointer();
1674   const char *loc=std::max_element(vals,vals+nbOfTuples);
1675   tupleId=(int)std::distance(vals,loc);
1676   return *loc;
1677 }
1678
1679 /*!
1680  * Returns the maximal value within \a this array that is allowed to have more than
1681  *  one component.
1682  *  \return char - the maximal value among all values of \a this array.
1683  *  \throw If \a this is not allocated.
1684  */
1685 char DataArrayChar::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
1686 {
1687   checkAllocated();
1688   const char *loc=std::max_element(begin(),end());
1689   return *loc;
1690 }
1691
1692 /*!
1693  * Returns the minimal value and its location within \a this one-dimensional array.
1694  *  \param [out] tupleId - index of the tuple holding the minimal value.
1695  *  \return char - the minimal value among all values of \a this array.
1696  *  \throw If \a this->getNumberOfComponents() != 1
1697  *  \throw If \a this->getNumberOfTuples() < 1
1698  */
1699 char DataArrayChar::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
1700 {
1701   checkAllocated();
1702   if(getNumberOfComponents()!=1)
1703     throw INTERP_KERNEL::Exception("DataArrayChar::getMaxValue : must be applied on DataArrayChar with only one component !");
1704   int nbOfTuples=getNumberOfTuples();
1705   if(nbOfTuples<=0)
1706     throw INTERP_KERNEL::Exception("DataArrayChar::getMaxValue : array exists but number of tuples must be > 0 !");
1707   const char *vals=getConstPointer();
1708   const char *loc=std::min_element(vals,vals+nbOfTuples);
1709   tupleId=(int)std::distance(vals,loc);
1710   return *loc;
1711 }
1712
1713 /*!
1714  * Returns the minimal value within \a this array that is allowed to have more than
1715  *  one component.
1716  *  \return char - the minimal value among all values of \a this array.
1717  *  \throw If \a this is not allocated.
1718  */
1719 char DataArrayChar::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
1720 {
1721   checkAllocated();
1722   const char *loc=std::min_element(begin(),end());
1723   return *loc;
1724 }
1725
1726 /*!
1727  * This method works only on data array with one component.
1728  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
1729  * this[*id] in [\b vmin,\b vmax)
1730  * 
1731  * \param [in] vmin begin of range. This value is included in range.
1732  * \param [out] vmax end of range. This value is \b not included in range.
1733  * \return a newly allocated data array that the caller should deal with.
1734  */
1735 DataArrayInt *DataArrayChar::getIdsInRange(char vmin, char vmax) const throw(INTERP_KERNEL::Exception)
1736 {
1737   checkAllocated();
1738   if(getNumberOfComponents()!=1)
1739     throw INTERP_KERNEL::Exception("DataArrayChar::getIdsInRange : this must have exactly one component !");
1740   const char *cptr=getConstPointer();
1741   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
1742   int nbOfTuples=getNumberOfTuples();
1743   for(int i=0;i<nbOfTuples;i++,cptr++)
1744     if(*cptr>=vmin && *cptr<vmax)
1745       ret->pushBackSilent(i);
1746   return ret.retn();
1747 }
1748
1749 /*!
1750  * Returns a new DataArrayChar by concatenating two given arrays, so that (1) the number
1751  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
1752  * offsetA2</em> and (2)
1753  * the number of component in the result array is same as that of each of given arrays.
1754  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
1755  * Info on components is copied from the first of the given arrays. Number of components
1756  * in the given arrays must be the same.
1757  *  \param [in] a1 - an array to include in the result array.
1758  *  \param [in] a2 - another array to include in the result array.
1759  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
1760  *  \return DataArrayChar * - the new instance of DataArrayChar.
1761  *          The caller is to delete this result array using decrRef() as it is no more
1762  *          needed.
1763  *  \throw If either \a a1 or \a a2 is NULL.
1764  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
1765  */
1766 DataArrayChar *DataArrayChar::Aggregate(const DataArrayChar *a1, const DataArrayChar *a2)
1767 {
1768   if(!a1 || !a2)
1769     throw INTERP_KERNEL::Exception("DataArrayChar::Aggregate : input DataArrayChar instance is NULL !");
1770   std::vector<const DataArrayChar *> v(2); v[0]=a1; v[1]=a2;
1771   return Aggregate(v);
1772 }
1773
1774 /*!
1775  * Returns a new DataArrayChar by concatenating all given arrays, so that (1) the number
1776  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
1777  * the number of component in the result array is same as that of each of given arrays.
1778  * Info on components is copied from the first of the given arrays. Number of components
1779  * in the given arrays must be  the same.
1780  *  \param [in] arr - a sequence of arrays to include in the result array.
1781  *  \return DataArrayChar * - the new instance of DataArrayChar.
1782  *          The caller is to delete this result array using decrRef() as it is no more
1783  *          needed.
1784  *  \throw If all arrays within \a arr are NULL.
1785  *  \throw If getNumberOfComponents() of arrays within \a arr.
1786  */
1787 DataArrayChar *DataArrayChar::Aggregate(const std::vector<const DataArrayChar *>& arr) throw(INTERP_KERNEL::Exception)
1788 {
1789   std::vector<const DataArrayChar *> a;
1790   for(std::vector<const DataArrayChar *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
1791     if(*it4)
1792       a.push_back(*it4);
1793   if(a.empty())
1794     throw INTERP_KERNEL::Exception("DataArrayChar::Aggregate : input list must be NON EMPTY !");
1795   std::vector<const DataArrayChar *>::const_iterator it=a.begin();
1796   int nbOfComp=(*it)->getNumberOfComponents();
1797   int nbt=(*it++)->getNumberOfTuples();
1798   for(int i=1;it!=a.end();it++,i++)
1799     {
1800       if((*it)->getNumberOfComponents()!=nbOfComp)
1801         throw INTERP_KERNEL::Exception("DataArrayChar::Aggregate : Nb of components mismatch for array aggregation !");
1802       nbt+=(*it)->getNumberOfTuples();
1803     }
1804   MEDCouplingAutoRefCountObjectPtr<DataArrayChar> ret=a[0]->buildEmptySpecializedDAChar();
1805   ret->alloc(nbt,nbOfComp);
1806   char *pt=ret->getPointer();
1807   for(it=a.begin();it!=a.end();it++)
1808     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
1809   ret->copyStringInfoFrom(*(a[0]));
1810   return ret.retn();
1811 }
1812
1813 /*!
1814  * Returns a new DataArrayChar by aggregating two given arrays, so that (1) the number
1815  * of components in the result array is a sum of the number of components of given arrays
1816  * and (2) the number of tuples in the result array is same as that of each of given
1817  * arrays. In other words the i-th tuple of result array includes all components of
1818  * i-th tuples of all given arrays.
1819  * Number of tuples in the given arrays must be the same.
1820  *  \param [in] a1 - an array to include in the result array.
1821  *  \param [in] a2 - another array to include in the result array.
1822  *  \return DataArrayChar * - the new instance of DataArrayChar.
1823  *          The caller is to delete this result array using decrRef() as it is no more
1824  *          needed.
1825  *  \throw If both \a a1 and \a a2 are NULL.
1826  *  \throw If any given array is not allocated.
1827  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
1828  */
1829 DataArrayChar *DataArrayChar::Meld(const DataArrayChar *a1, const DataArrayChar *a2) throw(INTERP_KERNEL::Exception)
1830 {
1831   std::vector<const DataArrayChar *> arr(2);
1832   arr[0]=a1; arr[1]=a2;
1833   return Meld(arr);
1834 }
1835
1836 /*!
1837  * Returns a new DataArrayChar by aggregating all given arrays, so that (1) the number
1838  * of components in the result array is a sum of the number of components of given arrays
1839  * and (2) the number of tuples in the result array is same as that of each of given
1840  * arrays. In other words the i-th tuple of result array includes all components of
1841  * i-th tuples of all given arrays.
1842  * Number of tuples in the given arrays must be  the same.
1843  *  \param [in] arr - a sequence of arrays to include in the result array.
1844  *  \return DataArrayChar * - the new instance of DataArrayChar.
1845  *          The caller is to delete this result array using decrRef() as it is no more
1846  *          needed.
1847  *  \throw If all arrays within \a arr are NULL.
1848  *  \throw If any given array is not allocated.
1849  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
1850  */
1851 DataArrayChar *DataArrayChar::Meld(const std::vector<const DataArrayChar *>& arr) throw(INTERP_KERNEL::Exception)
1852 {
1853   std::vector<const DataArrayChar *> a;
1854   for(std::vector<const DataArrayChar *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
1855     if(*it4)
1856       a.push_back(*it4);
1857   if(a.empty())
1858     throw INTERP_KERNEL::Exception("DataArrayChar::Meld : array must be NON empty !");
1859   std::vector<const DataArrayChar *>::const_iterator it;
1860   for(it=a.begin();it!=a.end();it++)
1861     (*it)->checkAllocated();
1862   it=a.begin();
1863   int nbOfTuples=(*it)->getNumberOfTuples();
1864   std::vector<int> nbc(a.size());
1865   std::vector<const char *> pts(a.size());
1866   nbc[0]=(*it)->getNumberOfComponents();
1867   pts[0]=(*it++)->getConstPointer();
1868   for(int i=1;it!=a.end();it++,i++)
1869     {
1870       if(nbOfTuples!=(*it)->getNumberOfTuples())
1871         throw INTERP_KERNEL::Exception("DataArrayChar::meld : mismatch of number of tuples !");
1872       nbc[i]=(*it)->getNumberOfComponents();
1873       pts[i]=(*it)->getConstPointer();
1874     }
1875   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
1876   DataArrayChar *ret=a[0]->buildEmptySpecializedDAChar();
1877   ret->alloc(nbOfTuples,totalNbOfComp);
1878   char *retPtr=ret->getPointer();
1879   for(int i=0;i<nbOfTuples;i++)
1880     for(int j=0;j<(int)a.size();j++)
1881       {
1882         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
1883         pts[j]+=nbc[j];
1884       }
1885   int k=0;
1886   for(int i=0;i<(int)a.size();i++)
1887     for(int j=0;j<nbc[i];j++,k++)
1888       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
1889   return ret;
1890 }
1891
1892 /*!
1893  * Sets a C array to be used as raw data of \a this. The previously set info
1894  *  of components is retained and re-sized. 
1895  * For more info see \ref MEDCouplingArraySteps1.
1896  *  \param [in] array - the C array to be used as raw data of \a this.
1897  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
1898  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
1899  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
1900  *                     \c free(\c array ) will be called.
1901  *  \param [in] nbOfTuple - new number of tuples in \a this.
1902  *  \param [in] nbOfCompo - new number of components in \a this.
1903  */
1904 void DataArrayChar::useArray(const char *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
1905 {
1906   _info_on_compo.resize(nbOfCompo);
1907   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
1908   declareAsNew();
1909 }
1910
1911 void DataArrayChar::useExternalArrayWithRWAccess(const char *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
1912 {
1913   _info_on_compo.resize(nbOfCompo);
1914   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
1915   declareAsNew();
1916 }
1917
1918 /*!
1919  * Returns a new instance of DataArrayByte. The caller is to delete this array
1920  * using decrRef() as it is no more needed. 
1921  */
1922 DataArrayByte *DataArrayByte::New()
1923 {
1924   return new DataArrayByte;
1925 }
1926
1927 DataArrayByteIterator *DataArrayByte::iterator()
1928 {
1929   return new DataArrayByteIterator(this);
1930 }
1931
1932 /*!
1933  * Returns a full copy of \a this. For more info on copying data arrays see
1934  * \ref MEDCouplingArrayBasicsCopyDeep.
1935  *  \return DataArrayByte * - a new instance of DataArrayByte.
1936  */
1937 DataArrayByte *DataArrayByte::deepCpy() const
1938 {
1939   return new DataArrayByte(*this);
1940 }
1941
1942 /*!
1943  * Returns either a \a deep or \a shallow copy of this array. For more info see
1944  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
1945  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
1946  *  \return DataArrayByte * - either a new instance of DataArrayByte (if \a dCpy
1947  *          == \a true) or \a this instance (if \a dCpy == \a false).
1948  */
1949 DataArrayByte *DataArrayByte::performCpy(bool dCpy) const
1950 {
1951   if(dCpy)
1952     return deepCpy();
1953   else
1954     {
1955       incrRef();
1956       return const_cast<DataArrayByte *>(this);
1957     }
1958 }
1959
1960 /*!
1961  * Returns the only one value in \a this, if and only if number of elements
1962  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
1963  *  \return double - the sole value stored in \a this array.
1964  *  \throw If at least one of conditions stated above is not fulfilled.
1965  */
1966 char DataArrayByte::byteValue() const throw(INTERP_KERNEL::Exception)
1967 {
1968   if(isAllocated())
1969     {
1970       if(getNbOfElems()==1)
1971         {
1972           return *getConstPointer();
1973         }
1974       else
1975         throw INTERP_KERNEL::Exception("DataArrayByte::byteValue : DataArrayByte instance is allocated but number of elements is not equal to 1 !");
1976     }
1977   else
1978     throw INTERP_KERNEL::Exception("DataArrayByte::byteValue : DataArrayByte instance is not allocated !");
1979 }
1980
1981 DataArrayChar *DataArrayByte::buildEmptySpecializedDAChar() const throw(INTERP_KERNEL::Exception)
1982 {
1983   return DataArrayByte::New();
1984 }
1985
1986 void DataArrayByte::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1987 {
1988   stream << "Name of byte array : \"" << _name << "\"\n";
1989   reprWithoutNameStream(stream);
1990 }
1991
1992 void DataArrayByte::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1993 {
1994   stream << "Name of byte array : \"" << _name << "\"\n";
1995   reprZipWithoutNameStream(stream);
1996 }
1997
1998 void DataArrayByte::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1999 {
2000   DataArray::reprWithoutNameStream(stream);
2001   if(_mem.reprHeader(getNumberOfComponents(),stream))
2002     {
2003       const char *data=begin();
2004       int nbOfTuples=getNumberOfTuples();
2005       int nbCompo=getNumberOfComponents();
2006       for(int i=0;i<nbOfTuples;i++,data+=nbCompo)
2007         {
2008           stream << "Tuple #" << i << " : ";
2009           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
2010           stream << "\n";
2011         }
2012     }
2013 }
2014
2015 void DataArrayByte::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
2016 {
2017   DataArray::reprWithoutNameStream(stream);
2018   _mem.reprZip(getNumberOfComponents(),stream);
2019 }
2020
2021 void DataArrayByte::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
2022 {
2023   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
2024   const char *data=getConstPointer();
2025   stream << "DataArrayByte *" << varName << "=DataArrayByte::New();" << std::endl;
2026   if(nbTuples*nbComp>=1)
2027     {
2028       stream << "const char " << varName << "Data[" << nbTuples*nbComp << "]={";
2029       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<char>(stream,","));
2030       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
2031       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
2032     }
2033   else
2034     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
2035   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
2036 }
2037
2038 /*!
2039  * Method that gives a quick overvien of \a this for python.
2040  */
2041 void DataArrayByte::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
2042 {
2043   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
2044   stream << "DataArrayByte C++ instance at " << this << ". ";
2045   if(isAllocated())
2046     {
2047       int nbOfCompo=(int)_info_on_compo.size();
2048       if(nbOfCompo>=1)
2049         {
2050           int nbOfTuples=getNumberOfTuples();
2051           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
2052           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
2053         }
2054       else
2055         stream << "Number of components : 0.";
2056     }
2057   else
2058     stream << "*** No data allocated ****";
2059 }
2060
2061 void DataArrayByte::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
2062 {
2063   const char *data=begin();
2064   int nbOfTuples=getNumberOfTuples();
2065   int nbOfCompo=(int)_info_on_compo.size();
2066   std::ostringstream oss2; oss2 << "[";
2067   std::string oss2Str(oss2.str());
2068   bool isFinished=true;
2069   for(int i=0;i<nbOfTuples && isFinished;i++)
2070     {
2071       if(nbOfCompo>1)
2072         {
2073           oss2 << "(";
2074           for(int j=0;j<nbOfCompo;j++,data++)
2075             {
2076               oss2 << (int)*data;
2077               if(j!=nbOfCompo-1) oss2 << ", ";
2078             }
2079           oss2 << ")";
2080         }
2081       else
2082         { oss2 << (int)*data; data++; }
2083       if(i!=nbOfTuples-1) oss2 << ", ";
2084       std::string oss3Str(oss2.str());
2085       if(oss3Str.length()<maxNbOfByteInRepr)
2086         oss2Str=oss3Str;
2087       else
2088         isFinished=false;
2089     }
2090   stream << oss2Str;
2091   if(!isFinished)
2092     stream << "... ";
2093   stream << "]";
2094 }
2095
2096 bool DataArrayByte::isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
2097 {
2098   const DataArrayByte *otherC=dynamic_cast<const DataArrayByte *>(&other);
2099   if(!otherC)
2100     { reason="this is of type DataArrayByte whereas other is not a DataArrayByte instance"; return false; }
2101   return DataArrayChar::isEqualIfNotWhy(other,reason);
2102 }
2103
2104 DataArrayByteIterator::DataArrayByteIterator(DataArrayByte *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
2105 {
2106   if(_da)
2107     {
2108       _da->incrRef();
2109       if(_da->isAllocated())
2110         {
2111           _nb_comp=da->getNumberOfComponents();
2112           _nb_tuple=da->getNumberOfTuples();
2113           _pt=da->getPointer();
2114         }
2115     }
2116 }
2117
2118 DataArrayByteIterator::~DataArrayByteIterator()
2119 {
2120   if(_da)
2121     _da->decrRef();
2122 }
2123
2124 DataArrayByteTuple *DataArrayByteIterator::nextt() throw(INTERP_KERNEL::Exception)
2125 {
2126   if(_tuple_id<_nb_tuple)
2127     {
2128       _tuple_id++;
2129       DataArrayByteTuple *ret=new DataArrayByteTuple(_pt,_nb_comp);
2130       _pt+=_nb_comp;
2131       return ret;
2132     }
2133   else
2134     return 0;
2135 }
2136
2137 DataArrayByteTuple::DataArrayByteTuple(char *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
2138 {
2139 }
2140
2141 std::string DataArrayByteTuple::repr() const throw(INTERP_KERNEL::Exception)
2142 {
2143   std::ostringstream oss; oss << "(";
2144   for(int i=0;i<_nb_of_compo-1;i++)
2145     oss << (int)_pt[i] << ", ";
2146   oss << _pt[_nb_of_compo-1] << ")";
2147   return oss.str();
2148 }
2149
2150 char DataArrayByteTuple::byteValue() const throw(INTERP_KERNEL::Exception)
2151 {
2152   if(_nb_of_compo==1)
2153     return *_pt;
2154   throw INTERP_KERNEL::Exception("DataArrayByteTuple::byteValue : DataArrayByteTuple instance has not exactly 1 component -> Not possible to convert it into an character !");
2155 }
2156
2157 /*!
2158  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayByte::decrRef.
2159  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayByte::useArray with ownership set to \b false.
2160  * This method throws an INTERP_KERNEL::Exception is it is impossible to match sizes of \b this that is too say \b nbOfCompo=this->_nb_of_elem and \bnbOfTuples==1 or
2161  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
2162  */
2163 DataArrayByte *DataArrayByteTuple::buildDAByte(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
2164 {
2165   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
2166     {
2167       DataArrayByte *ret=DataArrayByte::New();
2168       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
2169       return ret;
2170     }
2171   else
2172     {
2173       std::ostringstream oss; oss << "DataArrayByteTuple::buildDAByte : unable to build a requested DataArrayByte instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
2174       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
2175       throw INTERP_KERNEL::Exception(oss.str().c_str());
2176     }
2177 }
2178
2179 /*!
2180  * Returns a new instance of DataArrayAsciiChar. The caller is to delete this array
2181  * using decrRef() as it is no more needed. 
2182  */
2183 DataArrayAsciiChar *DataArrayAsciiChar::New()
2184 {
2185   return new DataArrayAsciiChar;
2186 }
2187
2188 /*!
2189  * Returns a new instance of DataArrayAsciiChar. The caller is to delete this array
2190  * using decrRef() as it is no more needed. 
2191  * \param [in] st the string. This input string should have a length greater than 0. If not an excpetion will be thrown.
2192  */
2193 DataArrayAsciiChar *DataArrayAsciiChar::New(const std::string& st) throw(INTERP_KERNEL::Exception)
2194 {
2195   return new DataArrayAsciiChar(st);
2196 }
2197
2198 /*!
2199  * \param [in] st the string. This input string should have a length greater than 0. If not an excpetion will be thrown.
2200  */
2201 DataArrayAsciiChar::DataArrayAsciiChar(const std::string& st) throw(INTERP_KERNEL::Exception)
2202 {
2203   std::size_t lgth=st.length();
2204   if(lgth==0)
2205     throw INTERP_KERNEL::Exception("DataArrayAsciiChar contructor with string ! Size of input string is null !");
2206   alloc(1,lgth);
2207   std::copy(st.begin(),st.begin()+lgth,getPointer());
2208 }
2209
2210 /*!
2211  * Returns a new instance of DataArrayAsciiChar. The caller is to delete this array
2212  * using decrRef() as it is no more needed. 
2213  * This constructor uses \a vst input vector of strings to initialize itself. For all strings whose length is lower than max length of strings in
2214  * \a vst the remaining locations in memory will be set to character \a defaultChar.
2215  *
2216  * \param [in] defaultChar the default character used to fill not defined locations in \a this
2217  * \param [in] vst vector of strings. This input vector must be non empty. \a this will have its component size set to the max lgth of strings contained
2218  *             in \a vst. If all strings are empty an INTERP_KERNEL::Exception will be thrown.
2219  *
2220  * \throw If input \a vst is empty.
2221  * \throw If all strings in \a vst are empty.
2222  */
2223 DataArrayAsciiChar *DataArrayAsciiChar::New(const std::vector<std::string>& vst, char defaultChar) throw(INTERP_KERNEL::Exception)
2224 {
2225   return new DataArrayAsciiChar(vst,defaultChar);
2226 }
2227
2228 /*!
2229  * This constructor uses \a vst input vector of strings to initialize itself. For all strings whose length is lower than max length of strings in
2230  * \a vst the remaining locations in memory will be set to character \a defaultChar.
2231  *
2232  * \param [in] defaultChar the default character used to fill not defined locations in \a this
2233  * \param [in] vst vector of strings. This input vector must be non empty. \a this will have its component size set to the max lgth of strings contained
2234  *             in \a vst. If all strings are empty an INTERP_KERNEL::Exception will be thrown.
2235  *
2236  * \throw If input \a vst is empty.
2237  * \throw If all strings in \a vst are empty.
2238  */
2239 DataArrayAsciiChar::DataArrayAsciiChar(const std::vector<std::string>& vst, char defaultChar) throw(INTERP_KERNEL::Exception)
2240 {
2241   if(vst.empty())
2242     throw INTERP_KERNEL::Exception("DataArrayAsciiChar contructor with vector of strings ! Empty array !");
2243   std::size_t nbCompo=0;
2244   for(std::vector<std::string>::const_iterator it=vst.begin();it!=vst.end();it++)
2245     nbCompo=std::max(nbCompo,(*it).length());
2246   if(nbCompo==0)
2247     throw INTERP_KERNEL::Exception("DataArrayAsciiChar contructor with vector of strings ! All strings in not empty vector are empty !");
2248   int nbTuples=(int)vst.size();
2249   alloc(nbTuples,(int)nbCompo);
2250   char *pt=getPointer();
2251   for(int i=0;i<nbTuples;i++,pt+=nbCompo)
2252     {
2253       const std::string& tmp=vst[i];
2254       std::size_t sz=tmp.length();
2255       std::copy(tmp.begin(),tmp.begin()+sz,pt);
2256       std::fill(pt+sz,pt+nbCompo,defaultChar);
2257     }
2258 }
2259
2260 DataArrayAsciiCharIterator *DataArrayAsciiChar::iterator()
2261 {
2262   return new DataArrayAsciiCharIterator(this);
2263 }
2264
2265 /*!
2266  * Returns a full copy of \a this. For more info on copying data arrays see
2267  * \ref MEDCouplingArrayBasicsCopyDeep.
2268  *  \return DataArrayAsciiChar * - a new instance of DataArrayAsciiChar.
2269  */
2270 DataArrayAsciiChar *DataArrayAsciiChar::deepCpy() const
2271 {
2272   return new DataArrayAsciiChar(*this);
2273 }
2274
2275 /*!
2276  * Returns either a \a deep or \a shallow copy of this array. For more info see
2277  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
2278  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
2279  *  \return DataArrayAsciiChar * - either a new instance of DataArrayAsciiChar (if \a dCpy
2280  *          == \a true) or \a this instance (if \a dCpy == \a false).
2281  */
2282 DataArrayAsciiChar *DataArrayAsciiChar::performCpy(bool dCpy) const
2283 {
2284   if(dCpy)
2285     return deepCpy();
2286   else
2287     {
2288       incrRef();
2289       return const_cast<DataArrayAsciiChar *>(this);
2290     }
2291 }
2292
2293 /*!
2294  * Returns the only one value in \a this, if and only if number of elements
2295  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
2296  *  \return double - the sole value stored in \a this array.
2297  *  \throw If at least one of conditions stated above is not fulfilled.
2298  */
2299 char DataArrayAsciiChar::asciiCharValue() const throw(INTERP_KERNEL::Exception)
2300 {
2301   if(isAllocated())
2302     {
2303       if(getNbOfElems()==1)
2304         {
2305           return *getConstPointer();
2306         }
2307       else
2308         throw INTERP_KERNEL::Exception("DataArrayAsciiChar::asciiCharValue : DataArrayAsciiChar instance is allocated but number of elements is not equal to 1 !");
2309     }
2310   else
2311     throw INTERP_KERNEL::Exception("DataArrayAsciiChar::asciiCharValue : DataArrayAsciiChar instance is not allocated !");
2312 }
2313
2314 DataArrayChar *DataArrayAsciiChar::buildEmptySpecializedDAChar() const throw(INTERP_KERNEL::Exception)
2315 {
2316   return DataArrayAsciiChar::New();
2317 }
2318
2319 void DataArrayAsciiChar::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
2320 {
2321   stream << "Name of ASCII char array : \"" << _name << "\"\n";
2322   reprWithoutNameStream(stream);
2323 }
2324
2325 void DataArrayAsciiChar::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
2326 {
2327   stream << "Name of ASCII char array : \"" << _name << "\"\n";
2328   reprZipWithoutNameStream(stream);
2329 }
2330
2331 void DataArrayAsciiChar::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
2332 {
2333   DataArray::reprWithoutNameStream(stream);
2334   if(_mem.reprHeader(getNumberOfComponents(),stream))
2335     {
2336       const char *data=begin();
2337       int nbOfTuples=getNumberOfTuples();
2338       int nbCompo=getNumberOfComponents();
2339       for(int i=0;i<nbOfTuples;i++,data+=nbCompo)
2340         {
2341           stream << "Tuple #" << i << " : \"";
2342           std::copy(data,data+nbCompo,std::ostream_iterator<char>(stream));
2343           stream << "\"\n";
2344         }
2345     }
2346 }
2347
2348 void DataArrayAsciiChar::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
2349 {
2350   reprWithoutNameStream(stream);
2351 }
2352
2353 void DataArrayAsciiChar::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
2354 {
2355   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
2356   const char *data=getConstPointer();
2357   stream << "DataArrayAsciiChar *" << varName << "=DataArrayAsciiChar::New();" << std::endl;
2358   if(nbTuples*nbComp>=1)
2359     {
2360       stream << "const char " << varName << "Data[" << nbTuples*nbComp << "]={";
2361       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<char>(stream,","));
2362       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
2363       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
2364     }
2365   else
2366     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
2367   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
2368 }
2369
2370 /*!
2371  * Method that gives a quick overvien of \a this for python.
2372  */
2373 void DataArrayAsciiChar::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
2374 {
2375   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
2376   stream << "DataArrayAsciiChar C++ instance at " << this << ". ";
2377   if(isAllocated())
2378     {
2379       int nbOfCompo=(int)_info_on_compo.size();
2380       if(nbOfCompo>=1)
2381         {
2382           int nbOfTuples=getNumberOfTuples();
2383           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
2384           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
2385         }
2386       else
2387         stream << "Number of components : 0.";
2388     }
2389   else
2390     stream << "*** No data allocated ****";
2391 }
2392
2393 void DataArrayAsciiChar::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
2394 {
2395   const char *data=begin();
2396   int nbOfTuples=getNumberOfTuples();
2397   int nbOfCompo=(int)_info_on_compo.size();
2398   std::ostringstream oss2; oss2 << "[";
2399   std::string oss2Str(oss2.str());
2400   bool isFinished=true;
2401   for(int i=0;i<nbOfTuples && isFinished;i++)
2402     {
2403       bool isAscii=true;
2404       for(int j=0;j<nbOfCompo;j++)
2405         if(data[j]<32) isAscii=false;
2406       if(isAscii)
2407         {
2408           oss2 << "\'";
2409           for(int j=0;j<nbOfCompo;j++,data++)
2410             oss2 << *data;
2411           oss2 << "\'";
2412         }
2413       else
2414         {
2415           oss2 << "(";
2416           for(int j=0;j<nbOfCompo;j++,data++)
2417             {
2418               oss2 << (int)*data;
2419               if(j!=nbOfCompo-1) oss2 << ", ";
2420             }
2421           oss2 << ")";
2422         }
2423       if(i!=nbOfTuples-1) oss2 << ", ";
2424       std::string oss3Str(oss2.str());
2425       if(oss3Str.length()<maxNbOfByteInRepr)
2426         oss2Str=oss3Str;
2427       else
2428         isFinished=false;
2429     }
2430   stream << oss2Str;
2431   if(!isFinished)
2432     stream << "... ";
2433   stream << "]";
2434 }
2435
2436 bool DataArrayAsciiChar::isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
2437 {
2438   const DataArrayAsciiChar *otherC=dynamic_cast<const DataArrayAsciiChar *>(&other);
2439   if(!otherC)
2440     { reason="this is of type DataArrayAsciiChar whereas other is not a DataArrayAsciiChar instance"; return false; }
2441   return DataArrayChar::isEqualIfNotWhy(other,reason);
2442 }
2443
2444 DataArrayAsciiCharIterator::DataArrayAsciiCharIterator(DataArrayAsciiChar *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
2445 {
2446   if(_da)
2447     {
2448       _da->incrRef();
2449       if(_da->isAllocated())
2450         {
2451           _nb_comp=da->getNumberOfComponents();
2452           _nb_tuple=da->getNumberOfTuples();
2453           _pt=da->getPointer();
2454         }
2455     }
2456 }
2457
2458 DataArrayAsciiCharIterator::~DataArrayAsciiCharIterator()
2459 {
2460   if(_da)
2461     _da->decrRef();
2462 }
2463
2464 DataArrayAsciiCharTuple *DataArrayAsciiCharIterator::nextt() throw(INTERP_KERNEL::Exception)
2465 {
2466   if(_tuple_id<_nb_tuple)
2467     {
2468       _tuple_id++;
2469       DataArrayAsciiCharTuple *ret=new DataArrayAsciiCharTuple(_pt,_nb_comp);
2470       _pt+=_nb_comp;
2471       return ret;
2472     }
2473   else
2474     return 0;
2475 }
2476
2477 DataArrayAsciiCharTuple::DataArrayAsciiCharTuple(char *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
2478 {
2479 }
2480
2481 std::string DataArrayAsciiCharTuple::repr() const throw(INTERP_KERNEL::Exception)
2482 {
2483   std::ostringstream oss;
2484   std::copy(_pt,_pt+_nb_of_compo,std::ostream_iterator<char>(oss));
2485   return oss.str();
2486 }
2487
2488 char DataArrayAsciiCharTuple::asciiCharValue() const throw(INTERP_KERNEL::Exception)
2489 {
2490   if(_nb_of_compo==1)
2491     return *_pt;
2492   throw INTERP_KERNEL::Exception("DataArrayAsciiCharTuple::asciiCharValue : DataArrayAsciiCharTuple instance has not exactly 1 component -> Not possible to convert it into an character !");
2493 }
2494
2495 /*!
2496  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayAsciiChar::decrRef.
2497  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayAsciiChar::useArray with ownership set to \b false.
2498  * This method throws an INTERP_KERNEL::Exception is it is impossible to match sizes of \b this that is too say \b nbOfCompo=this->_nb_of_elem and \bnbOfTuples==1 or
2499  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
2500  */
2501 DataArrayAsciiChar *DataArrayAsciiCharTuple::buildDAAsciiChar(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
2502 {
2503   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
2504     {
2505       DataArrayAsciiChar *ret=DataArrayAsciiChar::New();
2506       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
2507       return ret;
2508     }
2509   else
2510     {
2511       std::ostringstream oss; oss << "DataArrayAsciiCharTuple::buildDAAsciiChar : unable to build a requested DataArrayAsciiChar instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
2512       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
2513       throw INTERP_KERNEL::Exception(oss.str().c_str());
2514     }
2515 }