Salome HOME
08316a81e65429e14a2ae731f81266615e6813eb
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArrayChar.cxx
1 // Copyright (C) 2007-2016  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, or (at your option) any later version.
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 "MCAuto.hxx"
23
24 #include <set>
25 #include <cmath>
26 #include <limits>
27 #include <numeric>
28 #include <algorithm>
29 #include <functional>
30
31 using namespace MEDCoupling;
32
33 template class MEDCoupling::MemArray<char>;
34 template class MEDCoupling::DataArrayTemplate<char>;
35
36 /*!
37  * Returns an integer value characterizing \a this array, which is useful for a quick
38  * comparison of many instances of DataArrayInt.
39  *  \return int - the hash value.
40  *  \throw If \a this is not allocated.
41  */
42 int DataArrayChar::getHashCode() const
43 {
44   checkAllocated();
45   std::size_t nbOfElems=getNbOfElems();
46   int ret=nbOfElems*65536;
47   int delta=3;
48   if(nbOfElems>48)
49     delta=nbOfElems/8;
50   int ret0=0;
51   const char *pt=begin();
52   for(std::size_t i=0;i<nbOfElems;i+=delta)
53     ret0+=pt[i];
54   return ret+ret0;
55 }
56
57 /*!
58  * Checks if \a this and another DataArrayChar are fully equal. For more info see
59  * \ref MEDCouplingArrayBasicsCompare.
60  *  \param [in] other - an instance of DataArrayChar to compare with \a this one.
61  *  \return bool - \a true if the two arrays are equal, \a false else.
62  */
63 bool DataArrayChar::isEqual(const DataArrayChar& other) const
64 {
65   std::string tmp;
66   return isEqualIfNotWhy(other,tmp);
67 }
68
69 /*!
70  * Equivalent to DataArrayChar::isEqual except that if false the reason of
71  * mismatch is given.
72  * 
73  * \param [in] other the instance to be compared with \a this
74  * \param [out] reason In case of inequality returns the reason.
75  * \sa DataArrayChar::isEqual
76  */
77 bool DataArrayChar::isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const
78 {
79   if(!areInfoEqualsIfNotWhy(other,reason))
80     return false;
81   return _mem.isEqual(other._mem,0,reason);
82 }
83
84 /*!
85  * Checks if values of \a this and another DataArrayChar are equal. For more info see
86  * \ref MEDCouplingArrayBasicsCompare.
87  *  \param [in] other - an instance of DataArrayChar to compare with \a this one.
88  *  \return bool - \a true if the values of two arrays are equal, \a false else.
89  */
90 bool DataArrayChar::isEqualWithoutConsideringStr(const DataArrayChar& other) const
91 {
92   std::string tmp;
93   return _mem.isEqual(other._mem,0,tmp);
94 }
95
96 /*!
97  * Returns a textual and human readable representation of \a this instance of
98  * DataArrayChar. This text is shown when a DataArrayChar is printed in Python.
99  *  \return std::string - text describing \a this DataArrayChar.
100  */
101 std::string DataArrayChar::repr() const
102 {
103   std::ostringstream ret;
104   reprStream(ret);
105   return ret.str();
106 }
107
108 std::string DataArrayChar::reprZip() const
109 {
110   std::ostringstream ret;
111   reprZipStream(ret);
112   return ret.str();
113 }
114
115 /*!
116  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
117  * array to the new one.
118  *  \return DataArrayInt * - the new instance of DataArrayChar.
119  */
120 DataArrayInt *DataArrayChar::convertToIntArr() const
121 {
122   checkAllocated();
123   DataArrayInt *ret=DataArrayInt::New();
124   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
125   std::size_t nbOfVals=getNbOfElems();
126   const char *src=getConstPointer();
127   int *dest=ret->getPointer();
128   std::copy(src,src+nbOfVals,dest);
129   ret->copyStringInfoFrom(*this);
130   return ret;
131 }
132
133 /*!
134  * Checks if all values in \a this array are equal to \a val.
135  *  \param [in] val - value to check equality of array values to.
136  *  \return bool - \a true if all values are \a val.
137  *  \throw If \a this is not allocated.
138  *  \throw If \a this->getNumberOfComponents() != 1
139  */
140 bool DataArrayChar::isUniform(char val) const
141 {
142   checkAllocated();
143   if(getNumberOfComponents()!=1)
144     throw INTERP_KERNEL::Exception("DataArrayChar::isUniform : must be applied on DataArrayChar with only one component, you can call 'rearrange' method before !");
145   int nbOfTuples=getNumberOfTuples();
146   const char *w=getConstPointer();
147   const char *end2=w+nbOfTuples;
148   for(;w!=end2;w++)
149     if(*w!=val)
150       return false;
151   return true;
152 }
153
154 /*!
155  * Appends components of another array to components of \a this one, tuple by tuple.
156  * So that the number of tuples of \a this array remains the same and the number of 
157  * components increases.
158  *  \param [in] other - the DataArrayChar to append to \a this one.
159  *  \throw If \a this is not allocated.
160  *  \throw If \a this and \a other arrays have different number of tuples.
161  *
162  *  \if ENABLE_EXAMPLES
163  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
164  *
165  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
166  *  \endif
167  */
168 void DataArrayChar::meldWith(const DataArrayChar *other)
169 {
170   if(!other)
171     throw INTERP_KERNEL::Exception("DataArrayChar::meldWith : DataArrayChar pointer in input is NULL !");
172   checkAllocated();
173   other->checkAllocated();
174   int nbOfTuples=getNumberOfTuples();
175   if(nbOfTuples!=other->getNumberOfTuples())
176     throw INTERP_KERNEL::Exception("DataArrayChar::meldWith : mismatch of number of tuples !");
177   int nbOfComp1=getNumberOfComponents();
178   int nbOfComp2=other->getNumberOfComponents();
179   char *newArr=(char *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(char));
180   char *w=newArr;
181   const char *inp1=getConstPointer();
182   const char *inp2=other->getConstPointer();
183   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
184     {
185       w=std::copy(inp1,inp1+nbOfComp1,w);
186       w=std::copy(inp2,inp2+nbOfComp2,w);
187     }
188   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
189   std::vector<int> compIds(nbOfComp2);
190   for(int i=0;i<nbOfComp2;i++)
191     compIds[i]=nbOfComp1+i;
192   copyPartOfStringInfoFrom2(compIds,*other);
193 }
194
195 /*!
196  * Creates a new DataArrayChar containing IDs (indices) of tuples holding value equal to a
197  * given one.
198  *  \param [in] val - the value to find within \a this.
199  *  \return DataArrayChar * - a new instance of DataArrayChar. The caller is to delete this
200  *          array using decrRef() as it is no more needed.
201  *  \throw If \a this is not allocated.
202  *  \throw If \a this->getNumberOfComponents() != 1.
203  */
204 DataArrayInt *DataArrayChar::findIdsEqual(char val) const
205 {
206   checkAllocated();
207   if(getNumberOfComponents()!=1)
208     throw INTERP_KERNEL::Exception("DataArrayChar::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
209   const char *cptr=getConstPointer();
210   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
211   int nbOfTuples=getNumberOfTuples();
212   for(int i=0;i<nbOfTuples;i++,cptr++)
213     if(*cptr==val)
214       ret->pushBackSilent(i);
215   return ret.retn();
216 }
217
218 /*!
219  * Creates a new DataArrayChar containing IDs (indices) of tuples holding value \b not
220  * equal to a given one. 
221  *  \param [in] val - the value to ignore within \a this.
222  *  \return DataArrayChar * - a new instance of DataArrayChar. The caller is to delete this
223  *          array using decrRef() as it is no more needed.
224  *  \throw If \a this is not allocated.
225  *  \throw If \a this->getNumberOfComponents() != 1.
226  */
227 DataArrayInt *DataArrayChar::findIdsNotEqual(char val) const
228 {
229   checkAllocated();
230   if(getNumberOfComponents()!=1)
231     throw INTERP_KERNEL::Exception("DataArrayChar::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
232   const char *cptr=getConstPointer();
233   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
234   int nbOfTuples=getNumberOfTuples();
235   for(int i=0;i<nbOfTuples;i++,cptr++)
236     if(*cptr!=val)
237       ret->pushBackSilent(i);
238   return ret.retn();
239 }
240
241 /*!
242  * This method searches the sequence specified in input parameter \b vals in \b this.
243  * This works only for DataArrayChar having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
244  * This method differs from DataArrayChar::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayChar::findIdFirstEqualTuple.
245  * \sa DataArrayChar::findIdFirstEqualTuple
246  */
247 int DataArrayChar::findIdSequence(const std::vector<char>& vals) const
248 {
249   checkAllocated();
250   int nbOfCompo=getNumberOfComponents();
251   if(nbOfCompo!=1)
252     throw INTERP_KERNEL::Exception("DataArrayChar::findIdSequence : works only for DataArrayChar instance with one component !");
253   const char *cptr=getConstPointer();
254   std::size_t nbOfVals=getNbOfElems();
255   const char *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
256   if(loc!=cptr+nbOfVals)
257     return std::distance(cptr,loc);
258   return -1;
259 }
260
261 /*!
262  * This method is an extension of DataArrayChar::findIdFirstEqual method because this method works for DataArrayChar with
263  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
264  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
265  * If any the tuple id is returned. If not -1 is returned.
266  * 
267  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
268  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
269  *
270  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
271  * \sa DataArrayChar::findIdSequence.
272  */
273 int DataArrayChar::findIdFirstEqualTuple(const std::vector<char>& tupl) const
274 {
275   checkAllocated();
276   int nbOfCompo=getNumberOfComponents();
277   if(nbOfCompo==0)
278     throw INTERP_KERNEL::Exception("DataArrayChar::findIdFirstEqualTuple : 0 components in 'this' !");
279   if(nbOfCompo!=(int)tupl.size())
280     {
281       std::ostringstream oss; oss << "DataArrayChar::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
282       throw INTERP_KERNEL::Exception(oss.str().c_str());
283     }
284   const char *cptr=getConstPointer();
285   std::size_t nbOfVals=getNbOfElems();
286   for(const char *work=cptr;work!=cptr+nbOfVals;)
287     {
288       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
289       if(work!=cptr+nbOfVals)
290         {
291           if(std::distance(cptr,work)%nbOfCompo!=0)
292             work++;
293           else
294             return std::distance(cptr,work)/nbOfCompo;
295         }
296     }
297   return -1;
298 }
299
300 /*!
301  * This method is an extension of DataArrayChar::presenceOfValue method because this method works for DataArrayChar with
302  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
303  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
304  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
305  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
306  * \sa DataArrayChar::findIdFirstEqualTuple
307  */
308 bool DataArrayChar::presenceOfTuple(const std::vector<char>& tupl) const
309 {
310   return findIdFirstEqualTuple(tupl)!=-1;
311 }
312
313 /*!
314  * Returns \a true if a given value is present within \a this one-dimensional array.
315  *  \param [in] value - the value to find within \a this array.
316  *  \return bool - \a true in case if \a value is present within \a this array.
317  *  \throw If \a this is not allocated.
318  *  \throw If \a this->getNumberOfComponents() != 1.
319  *  \sa findIdFirstEqual()
320  */
321 bool DataArrayChar::presenceOfValue(char value) const
322 {
323   return findIdFirstEqual(value)!=-1;
324 }
325
326 /*!
327  * This method expects to be called when number of components of this is equal to one.
328  * This method returns true if it exists a tuple so that the value is contained in \b vals.
329  * If not any tuple contains one of the values contained in 'vals' false is returned.
330  * \sa DataArrayChar::findIdFirstEqual
331  */
332 bool DataArrayChar::presenceOfValue(const std::vector<char>& vals) const
333 {
334   return findIdFirstEqual(vals)!=-1;
335 }
336
337 /*!
338  * This method expects to be called when number of components of this is equal to one.
339  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
340  * If not any tuple contains \b value -1 is returned.
341  * \sa DataArrayChar::presenceOfValue
342  */
343 int DataArrayChar::findIdFirstEqual(char value) const
344 {
345   checkAllocated();
346   if(getNumberOfComponents()!=1)
347     throw INTERP_KERNEL::Exception("DataArrayChar::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
348   const char *cptr=getConstPointer();
349   int nbOfTuples=getNumberOfTuples();
350   const char *ret=std::find(cptr,cptr+nbOfTuples,value);
351   if(ret!=cptr+nbOfTuples)
352     return std::distance(cptr,ret);
353   return -1;
354 }
355
356 /*!
357  * This method expects to be called when number of components of this is equal to one.
358  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
359  * If not any tuple contains one of the values contained in 'vals' false is returned.
360  * \sa DataArrayChar::presenceOfValue
361  */
362 int DataArrayChar::findIdFirstEqual(const std::vector<char>& vals) const
363 {
364   checkAllocated();
365   if(getNumberOfComponents()!=1)
366     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
367   std::set<char> vals2(vals.begin(),vals.end());
368   const char *cptr=getConstPointer();
369   int nbOfTuples=getNumberOfTuples();
370   for(const char *w=cptr;w!=cptr+nbOfTuples;w++)
371     if(vals2.find(*w)!=vals2.end())
372       return std::distance(cptr,w);
373   return -1;
374 }
375
376 /*!
377  * This method works only on data array with one component.
378  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
379  * this[*id] in [\b vmin,\b vmax)
380  * 
381  * \param [in] vmin begin of range. This value is included in range.
382  * \param [in] vmax end of range. This value is \b not included in range.
383  * \return a newly allocated data array that the caller should deal with.
384  */
385 DataArrayInt *DataArrayChar::findIdsInRange(char vmin, char vmax) const
386 {
387   checkAllocated();
388   if(getNumberOfComponents()!=1)
389     throw INTERP_KERNEL::Exception("DataArrayChar::findIdsInRange : this must have exactly one component !");
390   const char *cptr=getConstPointer();
391   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
392   int nbOfTuples=getNumberOfTuples();
393   for(int i=0;i<nbOfTuples;i++,cptr++)
394     if(*cptr>=vmin && *cptr<vmax)
395       ret->pushBackSilent(i);
396   return ret.retn();
397 }
398
399 /*!
400  * Returns a new DataArrayChar by concatenating two given arrays, so that (1) the number
401  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
402  * offsetA2</em> and (2)
403  * the number of component in the result array is same as that of each of given arrays.
404  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
405  * Info on components is copied from the first of the given arrays. Number of components
406  * in the given arrays must be the same.
407  *  \param [in] a1 - an array to include in the result array.
408  *  \param [in] a2 - another array to include in the result array.
409  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
410  *  \return DataArrayChar * - the new instance of DataArrayChar.
411  *          The caller is to delete this result array using decrRef() as it is no more
412  *          needed.
413  *  \throw If either \a a1 or \a a2 is NULL.
414  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
415  */
416 DataArrayChar *DataArrayChar::Aggregate(const DataArrayChar *a1, const DataArrayChar *a2)
417 {
418   if(!a1 || !a2)
419     throw INTERP_KERNEL::Exception("DataArrayChar::Aggregate : input DataArrayChar instance is NULL !");
420   std::vector<const DataArrayChar *> v(2); v[0]=a1; v[1]=a2;
421   return Aggregate(v);
422 }
423
424 /*!
425  * Returns a new DataArrayChar by concatenating all given arrays, so that (1) the number
426  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
427  * the number of component in the result array is same as that of each of given arrays.
428  * Info on components is copied from the first of the given arrays. Number of components
429  * in the given arrays must be  the same.
430  *  \param [in] arr - a sequence of arrays to include in the result array.
431  *  \return DataArrayChar * - the new instance of DataArrayChar.
432  *          The caller is to delete this result array using decrRef() as it is no more
433  *          needed.
434  *  \throw If all arrays within \a arr are NULL.
435  *  \throw If getNumberOfComponents() of arrays within \a arr.
436  */
437 DataArrayChar *DataArrayChar::Aggregate(const std::vector<const DataArrayChar *>& arr)
438 {
439   std::vector<const DataArrayChar *> a;
440   for(std::vector<const DataArrayChar *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
441     if(*it4)
442       a.push_back(*it4);
443   if(a.empty())
444     throw INTERP_KERNEL::Exception("DataArrayChar::Aggregate : input list must be NON EMPTY !");
445   std::vector<const DataArrayChar *>::const_iterator it=a.begin();
446   std::size_t nbOfComp((*it)->getNumberOfComponents());
447   int nbt=(*it++)->getNumberOfTuples();
448   for(int i=1;it!=a.end();it++,i++)
449     {
450       if((*it)->getNumberOfComponents()!=nbOfComp)
451         throw INTERP_KERNEL::Exception("DataArrayChar::Aggregate : Nb of components mismatch for array aggregation !");
452       nbt+=(*it)->getNumberOfTuples();
453     }
454   MCAuto<DataArrayChar> ret=a[0]->buildEmptySpecializedDAChar();
455   ret->alloc(nbt,nbOfComp);
456   char *pt=ret->getPointer();
457   for(it=a.begin();it!=a.end();it++)
458     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
459   ret->copyStringInfoFrom(*(a[0]));
460   return ret.retn();
461 }
462
463 /*!
464  * Returns a new DataArrayChar by aggregating two given arrays, so that (1) the number
465  * of components in the result array is a sum of the number of components of given arrays
466  * and (2) the number of tuples in the result array is same as that of each of given
467  * arrays. In other words the i-th tuple of result array includes all components of
468  * i-th tuples of all given arrays.
469  * Number of tuples in the given arrays must be the same.
470  *  \param [in] a1 - an array to include in the result array.
471  *  \param [in] a2 - another array to include in the result array.
472  *  \return DataArrayChar * - the new instance of DataArrayChar.
473  *          The caller is to delete this result array using decrRef() as it is no more
474  *          needed.
475  *  \throw If both \a a1 and \a a2 are NULL.
476  *  \throw If any given array is not allocated.
477  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
478  */
479 DataArrayChar *DataArrayChar::Meld(const DataArrayChar *a1, const DataArrayChar *a2)
480 {
481   std::vector<const DataArrayChar *> arr(2);
482   arr[0]=a1; arr[1]=a2;
483   return Meld(arr);
484 }
485
486 /*!
487  * Returns a new DataArrayChar by aggregating all given arrays, so that (1) the number
488  * of components in the result array is a sum of the number of components of given arrays
489  * and (2) the number of tuples in the result array is same as that of each of given
490  * arrays. In other words the i-th tuple of result array includes all components of
491  * i-th tuples of all given arrays.
492  * Number of tuples in the given arrays must be  the same.
493  *  \param [in] arr - a sequence of arrays to include in the result array.
494  *  \return DataArrayChar * - the new instance of DataArrayChar.
495  *          The caller is to delete this result array using decrRef() as it is no more
496  *          needed.
497  *  \throw If all arrays within \a arr are NULL.
498  *  \throw If any given array is not allocated.
499  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
500  */
501 DataArrayChar *DataArrayChar::Meld(const std::vector<const DataArrayChar *>& arr)
502 {
503   std::vector<const DataArrayChar *> a;
504   for(std::vector<const DataArrayChar *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
505     if(*it4)
506       a.push_back(*it4);
507   if(a.empty())
508     throw INTERP_KERNEL::Exception("DataArrayChar::Meld : array must be NON empty !");
509   std::vector<const DataArrayChar *>::const_iterator it;
510   for(it=a.begin();it!=a.end();it++)
511     (*it)->checkAllocated();
512   it=a.begin();
513   int nbOfTuples=(*it)->getNumberOfTuples();
514   std::vector<int> nbc(a.size());
515   std::vector<const char *> pts(a.size());
516   nbc[0]=(*it)->getNumberOfComponents();
517   pts[0]=(*it++)->getConstPointer();
518   for(int i=1;it!=a.end();it++,i++)
519     {
520       if(nbOfTuples!=(*it)->getNumberOfTuples())
521         throw INTERP_KERNEL::Exception("DataArrayChar::meld : mismatch of number of tuples !");
522       nbc[i]=(*it)->getNumberOfComponents();
523       pts[i]=(*it)->getConstPointer();
524     }
525   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
526   DataArrayChar *ret=a[0]->buildEmptySpecializedDAChar();
527   ret->alloc(nbOfTuples,totalNbOfComp);
528   char *retPtr=ret->getPointer();
529   for(int i=0;i<nbOfTuples;i++)
530     for(int j=0;j<(int)a.size();j++)
531       {
532         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
533         pts[j]+=nbc[j];
534       }
535   int k=0;
536   for(int i=0;i<(int)a.size();i++)
537     for(int j=0;j<nbc[i];j++,k++)
538       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
539   return ret;
540 }
541
542 /*!
543  * Returns a new instance of DataArrayByte. The caller is to delete this array
544  * using decrRef() as it is no more needed. 
545  */
546 DataArrayByte *DataArrayByte::New()
547 {
548   return new DataArrayByte;
549 }
550
551 DataArrayByteIterator *DataArrayByte::iterator()
552 {
553   return new DataArrayByteIterator(this);
554 }
555
556 /*!
557  * Returns a full copy of \a this. For more info on copying data arrays see
558  * \ref MEDCouplingArrayBasicsCopyDeep.
559  *  \return DataArrayByte * - a new instance of DataArrayByte.
560  */
561 DataArrayByte *DataArrayByte::deepCopy() const
562 {
563   return new DataArrayByte(*this);
564 }
565
566 /*!
567  * Returns either a \a deep or \a shallow copy of this array. For more info see
568  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
569  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
570  *  \return DataArrayByte * - either a new instance of DataArrayByte (if \a dCpy
571  *          == \a true) or \a this instance (if \a dCpy == \a false).
572  */
573 DataArrayByte *DataArrayByte::performCopyOrIncrRef(bool dCpy) const
574 {
575   if(dCpy)
576     return deepCopy();
577   else
578     {
579       incrRef();
580       return const_cast<DataArrayByte *>(this);
581     }
582 }
583
584 /*!
585  * Returns the only one value in \a this, if and only if number of elements
586  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
587  *  \return char - the sole value stored in \a this array.
588  *  \throw If at least one of conditions stated above is not fulfilled.
589  */
590 char DataArrayByte::byteValue() const
591 {
592   if(isAllocated())
593     {
594       if(getNbOfElems()==1)
595         {
596           return *getConstPointer();
597         }
598       else
599         throw INTERP_KERNEL::Exception("DataArrayByte::byteValue : DataArrayByte instance is allocated but number of elements is not equal to 1 !");
600     }
601   else
602     throw INTERP_KERNEL::Exception("DataArrayByte::byteValue : DataArrayByte instance is not allocated !");
603 }
604
605 DataArrayChar *DataArrayByte::buildEmptySpecializedDAChar() const
606 {
607   return DataArrayByte::New();
608 }
609
610 void DataArrayByte::reprStream(std::ostream& stream) const
611 {
612   stream << "Name of byte array : \"" << _name << "\"\n";
613   reprWithoutNameStream(stream);
614 }
615
616 void DataArrayByte::reprZipStream(std::ostream& stream) const
617 {
618   stream << "Name of byte array : \"" << _name << "\"\n";
619   reprZipWithoutNameStream(stream);
620 }
621
622 void DataArrayByte::reprWithoutNameStream(std::ostream& stream) const
623 {
624   DataArray::reprWithoutNameStream(stream);
625   if(_mem.reprHeader(getNumberOfComponents(),stream))
626     {
627       const char *data=begin();
628       int nbOfTuples=getNumberOfTuples();
629       int nbCompo=getNumberOfComponents();
630       for(int i=0;i<nbOfTuples;i++,data+=nbCompo)
631         {
632           stream << "Tuple #" << i << " : ";
633           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
634           stream << "\n";
635         }
636     }
637 }
638
639 void DataArrayByte::reprZipWithoutNameStream(std::ostream& stream) const
640 {
641   DataArray::reprWithoutNameStream(stream);
642   _mem.reprZip(getNumberOfComponents(),stream);
643 }
644
645 void DataArrayByte::reprCppStream(const std::string& varName, std::ostream& stream) const
646 {
647   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
648   const char *data=getConstPointer();
649   stream << "DataArrayByte *" << varName << "=DataArrayByte::New();" << std::endl;
650   if(nbTuples*nbComp>=1)
651     {
652       stream << "const char " << varName << "Data[" << nbTuples*nbComp << "]={";
653       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<char>(stream,","));
654       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
655       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
656     }
657   else
658     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
659   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
660 }
661
662 /*!
663  * Method that gives a quick overvien of \a this for python.
664  */
665 void DataArrayByte::reprQuickOverview(std::ostream& stream) const
666 {
667   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
668   stream << "DataArrayByte C++ instance at " << this << ". ";
669   if(isAllocated())
670     {
671       int nbOfCompo=(int)_info_on_compo.size();
672       if(nbOfCompo>=1)
673         {
674           int nbOfTuples=getNumberOfTuples();
675           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
676           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
677         }
678       else
679         stream << "Number of components : 0.";
680     }
681   else
682     stream << "*** No data allocated ****";
683 }
684
685 void DataArrayByte::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
686 {
687   const char *data=begin();
688   int nbOfTuples=getNumberOfTuples();
689   int nbOfCompo=(int)_info_on_compo.size();
690   std::ostringstream oss2; oss2 << "[";
691   std::string oss2Str(oss2.str());
692   bool isFinished=true;
693   for(int i=0;i<nbOfTuples && isFinished;i++)
694     {
695       if(nbOfCompo>1)
696         {
697           oss2 << "(";
698           for(int j=0;j<nbOfCompo;j++,data++)
699             {
700               oss2 << (int)*data;
701               if(j!=nbOfCompo-1) oss2 << ", ";
702             }
703           oss2 << ")";
704         }
705       else
706         { oss2 << (int)*data; data++; }
707       if(i!=nbOfTuples-1) oss2 << ", ";
708       std::string oss3Str(oss2.str());
709       if(oss3Str.length()<maxNbOfByteInRepr)
710         oss2Str=oss3Str;
711       else
712         isFinished=false;
713     }
714   stream << oss2Str;
715   if(!isFinished)
716     stream << "... ";
717   stream << "]";
718 }
719
720 bool DataArrayByte::isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const
721 {
722   const DataArrayByte *otherC=dynamic_cast<const DataArrayByte *>(&other);
723   if(!otherC)
724     { reason="this is of type DataArrayByte whereas other is not a DataArrayByte instance"; return false; }
725   return DataArrayChar::isEqualIfNotWhy(other,reason);
726 }
727
728 /*!
729  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
730  * \throw if \a this is not allocated.
731  * \throw if \a this has not exactly one component.
732  */
733 std::vector<bool> DataArrayByte::toVectorOfBool() const
734 {
735   checkAllocated();
736   if(getNumberOfComponents()!=1)
737     throw INTERP_KERNEL::Exception("DataArrayByte::toVectorOfBool : this method can be used only if this has one component !");
738   int nbt(getNumberOfTuples());
739   std::vector<bool> ret(nbt,false);
740   const char *pt(begin());
741   for(int i=0;i<nbt;i++,pt++)
742     if(*pt!=0)
743       ret[i]=true;
744   return ret;
745 }
746
747 DataArrayByteIterator::DataArrayByteIterator(DataArrayByte *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
748 {
749   if(_da)
750     {
751       _da->incrRef();
752       if(_da->isAllocated())
753         {
754           _nb_comp=da->getNumberOfComponents();
755           _nb_tuple=da->getNumberOfTuples();
756           _pt=da->getPointer();
757         }
758     }
759 }
760
761 DataArrayByteIterator::~DataArrayByteIterator()
762 {
763   if(_da)
764     _da->decrRef();
765 }
766
767 DataArrayByteTuple *DataArrayByteIterator::nextt()
768 {
769   if(_tuple_id<_nb_tuple)
770     {
771       _tuple_id++;
772       DataArrayByteTuple *ret=new DataArrayByteTuple(_pt,_nb_comp);
773       _pt+=_nb_comp;
774       return ret;
775     }
776   else
777     return 0;
778 }
779
780 DataArrayByteTuple::DataArrayByteTuple(char *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
781 {
782 }
783
784 std::string DataArrayByteTuple::repr() const
785 {
786   std::ostringstream oss; oss << "(";
787   for(int i=0;i<_nb_of_compo-1;i++)
788     oss << (int)_pt[i] << ", ";
789   oss << _pt[_nb_of_compo-1] << ")";
790   return oss.str();
791 }
792
793 char DataArrayByteTuple::byteValue() const
794 {
795   if(_nb_of_compo==1)
796     return *_pt;
797   throw INTERP_KERNEL::Exception("DataArrayByteTuple::byteValue : DataArrayByteTuple instance has not exactly 1 component -> Not possible to convert it into an character !");
798 }
799
800 /*!
801  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayByte::decrRef.
802  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayByte::useArray with ownership set to \b false.
803  * 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
804  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
805  */
806 DataArrayByte *DataArrayByteTuple::buildDAByte(int nbOfTuples, int nbOfCompo) const
807 {
808   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
809     {
810       DataArrayByte *ret=DataArrayByte::New();
811       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
812       return ret;
813     }
814   else
815     {
816       std::ostringstream oss; oss << "DataArrayByteTuple::buildDAByte : unable to build a requested DataArrayByte instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
817       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
818       throw INTERP_KERNEL::Exception(oss.str().c_str());
819     }
820 }
821
822 /*!
823  * Returns a new instance of DataArrayAsciiChar. The caller is to delete this array
824  * using decrRef() as it is no more needed. 
825  */
826 DataArrayAsciiChar *DataArrayAsciiChar::New()
827 {
828   return new DataArrayAsciiChar;
829 }
830
831 /*!
832  * Returns a new instance of DataArrayAsciiChar. The caller is to delete this array
833  * using decrRef() as it is no more needed. 
834  * \param [in] st the string. This input string should have a length greater than 0. If not an excpetion will be thrown.
835  */
836 DataArrayAsciiChar *DataArrayAsciiChar::New(const std::string& st)
837 {
838   return new DataArrayAsciiChar(st);
839 }
840
841 /*!
842  * \param [in] st the string. This input string should have a length greater than 0. If not an excpetion will be thrown.
843  */
844 DataArrayAsciiChar::DataArrayAsciiChar(const std::string& st)
845 {
846   std::size_t lgth=st.length();
847   if(lgth==0)
848     throw INTERP_KERNEL::Exception("DataArrayAsciiChar contructor with string ! Size of input string is null !");
849   alloc(1,lgth);
850   std::copy(st.begin(),st.begin()+lgth,getPointer());
851 }
852
853 /*!
854  * Returns a new instance of DataArrayAsciiChar. The caller is to delete this array
855  * using decrRef() as it is no more needed. 
856  * 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
857  * \a vst the remaining locations in memory will be set to character \a defaultChar.
858  *
859  * \param [in] defaultChar the default character used to fill not defined locations in \a this
860  * \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
861  *             in \a vst. If all strings are empty an INTERP_KERNEL::Exception will be thrown.
862  *
863  * \throw If input \a vst is empty.
864  * \throw If all strings in \a vst are empty.
865  */
866 DataArrayAsciiChar *DataArrayAsciiChar::New(const std::vector<std::string>& vst, char defaultChar)
867 {
868   return new DataArrayAsciiChar(vst,defaultChar);
869 }
870
871 /*!
872  * 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
873  * \a vst the remaining locations in memory will be set to character \a defaultChar.
874  *
875  * \param [in] defaultChar the default character used to fill not defined locations in \a this
876  * \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
877  *             in \a vst. If all strings are empty an INTERP_KERNEL::Exception will be thrown.
878  *
879  * \throw If input \a vst is empty.
880  * \throw If all strings in \a vst are empty.
881  */
882 DataArrayAsciiChar::DataArrayAsciiChar(const std::vector<std::string>& vst, char defaultChar)
883 {
884   if(vst.empty())
885     throw INTERP_KERNEL::Exception("DataArrayAsciiChar contructor with vector of strings ! Empty array !");
886   std::size_t nbCompo=0;
887   for(std::vector<std::string>::const_iterator it=vst.begin();it!=vst.end();it++)
888     nbCompo=std::max(nbCompo,(*it).length());
889   if(nbCompo==0)
890     throw INTERP_KERNEL::Exception("DataArrayAsciiChar contructor with vector of strings ! All strings in not empty vector are empty !");
891   int nbTuples=(int)vst.size();
892   alloc(nbTuples,(int)nbCompo);
893   char *pt=getPointer();
894   for(int i=0;i<nbTuples;i++,pt+=nbCompo)
895     {
896       const std::string& tmp=vst[i];
897       std::size_t sz=tmp.length();
898       std::copy(tmp.begin(),tmp.begin()+sz,pt);
899       std::fill(pt+sz,pt+nbCompo,defaultChar);
900     }
901 }
902
903 DataArrayAsciiCharIterator *DataArrayAsciiChar::iterator()
904 {
905   return new DataArrayAsciiCharIterator(this);
906 }
907
908 /*!
909  * Returns a full copy of \a this. For more info on copying data arrays see
910  * \ref MEDCouplingArrayBasicsCopyDeep.
911  *  \return DataArrayAsciiChar * - a new instance of DataArrayAsciiChar.
912  */
913 DataArrayAsciiChar *DataArrayAsciiChar::deepCopy() const
914 {
915   return new DataArrayAsciiChar(*this);
916 }
917
918 /*!
919  * Returns either a \a deep or \a shallow copy of this array. For more info see
920  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
921  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
922  *  \return DataArrayAsciiChar * - either a new instance of DataArrayAsciiChar (if \a dCpy
923  *          == \a true) or \a this instance (if \a dCpy == \a false).
924  */
925 DataArrayAsciiChar *DataArrayAsciiChar::performCopyOrIncrRef(bool dCpy) const
926 {
927   if(dCpy)
928     return deepCopy();
929   else
930     {
931       incrRef();
932       return const_cast<DataArrayAsciiChar *>(this);
933     }
934 }
935
936 /*!
937  * Returns the only one value in \a this, if and only if number of elements
938  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
939  *  \return char - the sole value stored in \a this array.
940  *  \throw If at least one of conditions stated above is not fulfilled.
941  */
942 char DataArrayAsciiChar::asciiCharValue() const
943 {
944   if(isAllocated())
945     {
946       if(getNbOfElems()==1)
947         {
948           return *getConstPointer();
949         }
950       else
951         throw INTERP_KERNEL::Exception("DataArrayAsciiChar::asciiCharValue : DataArrayAsciiChar instance is allocated but number of elements is not equal to 1 !");
952     }
953   else
954     throw INTERP_KERNEL::Exception("DataArrayAsciiChar::asciiCharValue : DataArrayAsciiChar instance is not allocated !");
955 }
956
957 DataArrayChar *DataArrayAsciiChar::buildEmptySpecializedDAChar() const
958 {
959   return DataArrayAsciiChar::New();
960 }
961
962 void DataArrayAsciiChar::reprStream(std::ostream& stream) const
963 {
964   stream << "Name of ASCII char array : \"" << _name << "\"\n";
965   reprWithoutNameStream(stream);
966 }
967
968 void DataArrayAsciiChar::reprZipStream(std::ostream& stream) const
969 {
970   stream << "Name of ASCII char array : \"" << _name << "\"\n";
971   reprZipWithoutNameStream(stream);
972 }
973
974 void DataArrayAsciiChar::reprWithoutNameStream(std::ostream& stream) const
975 {
976   DataArray::reprWithoutNameStream(stream);
977   if(_mem.reprHeader(getNumberOfComponents(),stream))
978     {
979       const char *data=begin();
980       int nbOfTuples=getNumberOfTuples();
981       int nbCompo=getNumberOfComponents();
982       for(int i=0;i<nbOfTuples;i++,data+=nbCompo)
983         {
984           stream << "Tuple #" << i << " : \"";
985           std::copy(data,data+nbCompo,std::ostream_iterator<char>(stream));
986           stream << "\"\n";
987         }
988     }
989 }
990
991 void DataArrayAsciiChar::reprZipWithoutNameStream(std::ostream& stream) const
992 {
993   reprWithoutNameStream(stream);
994 }
995
996 void DataArrayAsciiChar::reprCppStream(const std::string& varName, std::ostream& stream) const
997 {
998   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
999   const char *data=getConstPointer();
1000   stream << "DataArrayAsciiChar *" << varName << "=DataArrayAsciiChar::New();" << std::endl;
1001   if(nbTuples*nbComp>=1)
1002     {
1003       stream << "const char " << varName << "Data[" << nbTuples*nbComp << "]={";
1004       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<char>(stream,","));
1005       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1006       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1007     }
1008   else
1009     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1010   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1011 }
1012
1013 /*!
1014  * Method that gives a quick overvien of \a this for python.
1015  */
1016 void DataArrayAsciiChar::reprQuickOverview(std::ostream& stream) const
1017 {
1018   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1019   stream << "DataArrayAsciiChar C++ instance at " << this << ". ";
1020   if(isAllocated())
1021     {
1022       int nbOfCompo=(int)_info_on_compo.size();
1023       if(nbOfCompo>=1)
1024         {
1025           int nbOfTuples=getNumberOfTuples();
1026           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1027           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1028         }
1029       else
1030         stream << "Number of components : 0.";
1031     }
1032   else
1033     stream << "*** No data allocated ****";
1034 }
1035
1036 void DataArrayAsciiChar::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1037 {
1038   const char *data=begin();
1039   int nbOfTuples=getNumberOfTuples();
1040   int nbOfCompo=(int)_info_on_compo.size();
1041   std::ostringstream oss2; oss2 << "[";
1042   std::string oss2Str(oss2.str());
1043   bool isFinished=true;
1044   for(int i=0;i<nbOfTuples && isFinished;i++)
1045     {
1046       bool isAscii=true;
1047       for(int j=0;j<nbOfCompo;j++)
1048         if(data[j]<32) isAscii=false;
1049       if(isAscii)
1050         {
1051           oss2 << "\'";
1052           for(int j=0;j<nbOfCompo;j++,data++)
1053             oss2 << *data;
1054           oss2 << "\'";
1055         }
1056       else
1057         {
1058           oss2 << "(";
1059           for(int j=0;j<nbOfCompo;j++,data++)
1060             {
1061               oss2 << (int)*data;
1062               if(j!=nbOfCompo-1) oss2 << ", ";
1063             }
1064           oss2 << ")";
1065         }
1066       if(i!=nbOfTuples-1) oss2 << ", ";
1067       std::string oss3Str(oss2.str());
1068       if(oss3Str.length()<maxNbOfByteInRepr)
1069         oss2Str=oss3Str;
1070       else
1071         isFinished=false;
1072     }
1073   stream << oss2Str;
1074   if(!isFinished)
1075     stream << "... ";
1076   stream << "]";
1077 }
1078
1079 bool DataArrayAsciiChar::isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const
1080 {
1081   const DataArrayAsciiChar *otherC=dynamic_cast<const DataArrayAsciiChar *>(&other);
1082   if(!otherC)
1083     { reason="this is of type DataArrayAsciiChar whereas other is not a DataArrayAsciiChar instance"; return false; }
1084   return DataArrayChar::isEqualIfNotWhy(other,reason);
1085 }
1086
1087 DataArrayAsciiCharIterator::DataArrayAsciiCharIterator(DataArrayAsciiChar *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
1088 {
1089   if(_da)
1090     {
1091       _da->incrRef();
1092       if(_da->isAllocated())
1093         {
1094           _nb_comp=da->getNumberOfComponents();
1095           _nb_tuple=da->getNumberOfTuples();
1096           _pt=da->getPointer();
1097         }
1098     }
1099 }
1100
1101 DataArrayAsciiCharIterator::~DataArrayAsciiCharIterator()
1102 {
1103   if(_da)
1104     _da->decrRef();
1105 }
1106
1107 DataArrayAsciiCharTuple *DataArrayAsciiCharIterator::nextt()
1108 {
1109   if(_tuple_id<_nb_tuple)
1110     {
1111       _tuple_id++;
1112       DataArrayAsciiCharTuple *ret=new DataArrayAsciiCharTuple(_pt,_nb_comp);
1113       _pt+=_nb_comp;
1114       return ret;
1115     }
1116   else
1117     return 0;
1118 }
1119
1120 DataArrayAsciiCharTuple::DataArrayAsciiCharTuple(char *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
1121 {
1122 }
1123
1124 std::string DataArrayAsciiCharTuple::repr() const
1125 {
1126   std::ostringstream oss;
1127   std::copy(_pt,_pt+_nb_of_compo,std::ostream_iterator<char>(oss));
1128   return oss.str();
1129 }
1130
1131 char DataArrayAsciiCharTuple::asciiCharValue() const
1132 {
1133   if(_nb_of_compo==1)
1134     return *_pt;
1135   throw INTERP_KERNEL::Exception("DataArrayAsciiCharTuple::asciiCharValue : DataArrayAsciiCharTuple instance has not exactly 1 component -> Not possible to convert it into an character !");
1136 }
1137
1138 /*!
1139  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayAsciiChar::decrRef.
1140  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayAsciiChar::useArray with ownership set to \b false.
1141  * 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
1142  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
1143  */
1144 DataArrayAsciiChar *DataArrayAsciiCharTuple::buildDAAsciiChar(int nbOfTuples, int nbOfCompo) const
1145 {
1146   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
1147     {
1148       DataArrayAsciiChar *ret=DataArrayAsciiChar::New();
1149       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
1150       return ret;
1151     }
1152   else
1153     {
1154       std::ostringstream oss; oss << "DataArrayAsciiCharTuple::buildDAAsciiChar : unable to build a requested DataArrayAsciiChar instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
1155       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
1156       throw INTERP_KERNEL::Exception(oss.str().c_str());
1157     }
1158 }