Index: XIOS/trunk/src/array_new.hpp
===================================================================
--- XIOS/trunk/src/array_new.hpp	(revision 1049)
+++ XIOS/trunk/src/array_new.hpp	(revision 1050)
@@ -539,5 +539,5 @@
         TinyVector<int,N_rank> vect;
         size_t ne;
-
+        
         ret =  buffer.get(numDim);
         ret &= buffer.get(vect.data(), N_rank);
@@ -551,4 +551,79 @@
       }
   };
+
+
+#define macro(NRANK)\
+\
+  template <>\
+  inline size_t CArray<StdString,NRANK>::size(void) const\
+  {\
+    size_t size=(1 + NRANK) * sizeof(int) ;\
+    Array<StdString,NRANK>::const_iterator it, itb=this->begin(), ite=this->end() ;\
+\
+    for(it=itb;it!=ite;++it)\
+    {\
+      size+= sizeof(size_t) ;\
+      size+= (*it).size();\
+    } \
+    return size ;\
+  }\
+\
+/* for array string this function is an evaluation of maximum size of the array, considering stringArrayLen is the maximum size of the strings*/ \
+  template <>\
+  inline size_t CArray<StdString,NRANK>::size(sizeType numElements)\
+  {\
+    return (NRANK + 1) * sizeof(int) + numElements * stringArrayLen;\
+  }\
+  \
+  template <>\
+  inline bool CArray<StdString,NRANK>::toBuffer(CBufferOut& buffer) const\
+  {\
+    bool ret;\
+    ret =  buffer.put(this->dimensions());\
+    ret &= buffer.put(this->shape().data(), this->dimensions());\
+\
+    Array<StdString,NRANK>::const_iterator it, itb=this->begin(), ite=this->end() ;\
+\
+    for(it=itb;it!=ite;++it)\
+    {\
+      ret &= buffer.put((*it).size()) ;\
+      ret &= buffer.put((*it).data(),(*it).size());\
+    } \
+    return ret;\
+  }\
+\
+  template <>\
+  inline bool CArray<StdString,NRANK>::fromBuffer(CBufferIn& buffer)\
+  {\
+     bool ret;\
+     int numDim;\
+     TinyVector<int,NRANK> vect;\
+     size_t ne;\
+\
+     ret =  buffer.get(numDim);\
+     ret &= buffer.get(vect.data(), NRANK);\
+     this->resize(vect);\
+\
+     Array<StdString,NRANK>::iterator it, itb=this->begin(), ite=this->end() ;\
+     for(it=itb;it!=ite;++it)\
+     {\
+       ret &= buffer.get(ne) ;\
+       char* str = new char[ne] ;\
+       ret &= buffer.get(str, ne);\
+       *it = string(str,ne) ;\
+       delete [] str ;\
+     }\
+     initialized = true;\
+     return ret;\
+  }
+macro(1)
+macro(2)
+macro(3)
+macro(4)
+macro(5)
+macro(6)
+macro(7)
+
+#undef macro
 
   template <typename T_numtype,int N_rank> inline CBufferOut& operator<<(CBufferOut& buffer, const CArray<T_numtype,N_rank>& array)
Index: XIOS/trunk/src/attribute_array_decl.cpp
===================================================================
--- XIOS/trunk/src/attribute_array_decl.cpp	(revision 1049)
+++ XIOS/trunk/src/attribute_array_decl.cpp	(revision 1050)
@@ -17,3 +17,5 @@
   template class CAttributeArray<bool,6> ;
   template class CAttributeArray<bool,7> ;
+  template class CAttributeArray<StdString,1> ;
+  template class CAttributeArray<StdString,2> ;
 }
Index: XIOS/trunk/src/config/axis_attribute.conf
===================================================================
--- XIOS/trunk/src/config/axis_attribute.conf	(revision 1049)
+++ XIOS/trunk/src/config/axis_attribute.conf	(revision 1050)
@@ -30,2 +30,3 @@
 DECLARE_ARRAY(double, 2 , bounds)
 DECLARE_ATTRIBUTE(int,       prec)
+DECLARE_ARRAY(StdString    ,1    , label)
Index: XIOS/trunk/src/generate_interface_impl.hpp
===================================================================
--- XIOS/trunk/src/generate_interface_impl.hpp	(revision 1049)
+++ XIOS/trunk/src/generate_interface_impl.hpp	(revision 1050)
@@ -547,4 +547,36 @@
 #undef macro
 
+#define macro(N,EXTENT)\
+  template <>\
+  void CInterface::AttributeCInterface<CArray<StdString,N> >(ostream& oss, const string& className, const string& name)\
+  { \
+    oss << "void cxios_set_" << className << "_" << name << "(" << className << "_Ptr " << className << "_hdl, " << "char* " << name <<", int str_len, int* str_size, int* extent)" << iendl; \
+    oss << "{" << iendl; \
+    oss << "  CTimer::get(\"XIOS\").resume();" << iendl; \
+    oss << "  "<<className<<"_hdl->"<<name<<".resize(shape("<<EXTENT<<"));"<<iendl;\
+    oss << "  Array<StdString,"<<#N<<">::iterator it, itb="<<className<<"_hdl->"<<name<<".begin(), ite="<<className<<"_hdl->"<<name<<".end() ;"<<iendl ;\
+    oss << "  int i, n ;"<< iendl; \
+    oss << "  for(it=itb, i=0, n=0 ; it!=ite ; ++it,n+=str_len,++i) *it=StdString(&"<<name<<"[n],str_size[i]) ;"<<iendl ;\
+    oss << "  CTimer::get(\"XIOS\").suspend();" << iendl; \
+    oss << "}" << std::endl; \
+    oss << iendl; \
+    oss << "void cxios_get_" << className << "_" << name << "(" << className << "_Ptr " << className << "_hdl, " << "char* " << name << ", int str_size, int* extent)" << iendl; \
+    oss << "{" << iendl; \
+    oss << "  CTimer::get(\"XIOS\").resume();" << iendl; \
+    oss << "  Array<StdString,"<<#N<<">::const_iterator it, itb="<<className<<"_hdl->"<<name<<".getInheritedValue().begin(), ite="<<className<<"_hdl->"<<name<<".getInheritedValue().end() ;" << iendl; \
+    oss << "  int n ;"<< iendl; \
+    oss << "  for(it=itb, n=0 ; it!=ite ; ++it, n+=str_size) it->copy(&"<<name<<"[n],it->size()) ; "<< iendl; \
+    oss << "  CTimer::get(\"XIOS\").suspend();" << iendl; \
+    oss << "}" << std::endl; \
+  }
+
+macro(1,"extent[0]")
+macro(2,"extent[0],extent[1]")
+macro(3,"extent[0],extent[1],extent[2]")
+macro(4,"extent[0],extent[1],extent[2],extent[3]")
+macro(5,"extent[0],extent[1],extent[2],extent[3],extent[4]")
+macro(6,"extent[0],extent[1],extent[2],extent[3],extent[4],extent[5]")
+macro(7,"extent[0],extent[1],extent[2],extent[3],extent[4],extent[5],extent[6]")
+#undef macro
 // /////////////////////////////////////////////////
 // //          Fortran 2003 Interface             //
@@ -705,4 +737,35 @@
   #undef macro
 
+#define macro(T)\
+  template <>\
+  void CInterface::AttributeFortran2003Interface<CArray<StdString,T> >(ostream& oss, const string& className, const string& name)\
+  {\
+    oss << "SUBROUTINE cxios_set_" << className << "_" << name << "(" << className << "_hdl, " << name << ", str_len, str_size, extent) BIND(C)" << iendl; \
+    oss << "  USE ISO_C_BINDING" << iendl; \
+    oss << "  INTEGER (kind = C_INTPTR_T), VALUE       :: " << className << "_hdl" << iendl; \
+    oss << "  CHARACTER (KIND=C_CHAR), DIMENSION(*)    :: " << name << iendl; \
+    oss << "  INTEGER (kind = C_INT), VALUE            :: str_len" << iendl; \
+    oss << "  INTEGER (kind = C_INT), DIMENSION(*)     :: str_size" << iendl; \
+    oss << "  INTEGER (kind = C_INT), DIMENSION(*)     :: extent" << iendl; \
+    oss << "END SUBROUTINE cxios_set_" << className << "_" << name << std::endl; \
+    oss << iendl; \
+    oss << "SUBROUTINE cxios_get_" << className << "_" << name << "(" << className << "_hdl, " << name << ", str_size, extent) BIND(C)" << iendl; \
+    oss << "  USE ISO_C_BINDING" << iendl; \
+    oss << "  INTEGER (kind = C_INTPTR_T), VALUE       :: " << className << "_hdl" << iendl; \
+    oss << "  CHARACTER (KIND=C_CHAR), DIMENSION(*)    :: " << name << iendl; \
+    oss << "  INTEGER (kind = C_INT), VALUE            :: str_size" << iendl; \
+    oss << "  INTEGER (kind = C_INT), DIMENSION(*)     :: extent" << iendl; \
+    oss << "END SUBROUTINE cxios_get_" << className << "_" << name << std::endl; \
+  }
+  macro(1)
+  macro(2)
+  macro(3)
+  macro(4)
+  macro(5)
+  macro(6)
+  macro(7)
+
+#undef macro
+
 #define macro(T) \
   template <> \
@@ -808,4 +871,31 @@
 
 #undef macro
+
+#define macro(T,EXTENT)\
+  template <> \
+  void CInterface::AttributeFortranInterfaceDeclaration<CArray<StdString,T> >(ostream& oss, const string& className, const string& name)\
+  {\
+    oss << "CHARACTER(len=*) , OPTIONAL, INTENT(IN) :: " << name << "("<<EXTENT<<")"; \
+  }\
+\
+  template <>\ 
+  void CInterface::AttributeFortranInterfaceGetDeclaration<CArray<StdString,T> >(ostream& oss, const string& className, const string& name)\
+  {\
+    oss << "CHARACTER(len=*) , OPTIONAL, INTENT(OUT) :: " << name << "("<<EXTENT<<")"; \
+  }
+  macro(1,":")
+  macro(2,":,:")
+  macro(3,":,:,:")
+  macro(4,":,:,:,:")
+  macro(5,":,:,:,:,:")
+  macro(6,":,:,:,:,:,:")
+  macro(7,":,:,:,:,:,:,:")
+
+#undef macro
+
+
+
+
+  
 
 #define macro(T) \
@@ -947,4 +1037,18 @@
 #undef macro
 
+#define macro(T)\
+  template <>\
+  void CInterface::AttributeFortranInterfaceBody< CArray<StdString,T> >(ostream& oss, const string& className, const string& name)\
+  {\
+     oss << "IF (PRESENT(" << name << "_)) THEN" << iendl; \
+     oss << "  CALL cxios_set_" << className << "_" << name << " &" << iendl; \
+     oss << "(" << className << "_hdl%daddr, " << name <<"_, LEN("<<name<<"_), LEN_TRIM("<<name<< "_), SHAPE(" << name << "_))" << iendl; \
+     oss << "ENDIF"; \
+  }
+
+  macro(1)
+  macro(2)
+#undef macro
+
 #define macro(T) \
   template <>  \
@@ -1084,4 +1188,24 @@
 
 #undef macro
+
+#define macro(T)\
+  template <> \
+  void CInterface::AttributeFortranInterfaceGetBody< CArray<StdString,T> >(ostream& oss, const string& className, const string& name)\
+  {\
+    oss << "IF (PRESENT(" << name << "_)) THEN" << iendl; \
+    oss << "  CALL cxios_get_" << className << "_" << name << " &" << iendl; \
+    oss << "(" << className << "_hdl%daddr, " << name << "_, LEN("<<name<<"_), SHAPE(" << name << "_))" << iendl; \
+    oss << "ENDIF"; \
+  }
+  macro(1)
+  macro(2)
+  macro(3)
+  macro(4)
+  macro(5)
+  macro(6)
+  macro(7)
+
+#undef macro
+  
 }
 #endif
Index: XIOS/trunk/src/io/nc4_data_output.cpp
===================================================================
--- XIOS/trunk/src/io/nc4_data_output.cpp	(revision 1049)
+++ XIOS/trunk/src/io/nc4_data_output.cpp	(revision 1050)
@@ -1060,10 +1060,14 @@
         else if (axis->prec==8)   typePrec =  NC_DOUBLE ;
          
+        if (!axis->label.isEmpty()) typePrec = NC_CHAR ;
+        string strId="str_len" ;
         try
         {
           SuperClassWriter::addDimension(axisid, zoom_size);
+          if (!axis->label.isEmpty()) SuperClassWriter::addDimension(strId, stringArrayLen);
           if (axis->hasValue)
           {
             dims.push_back(axisid);
+            if (!axis->label.isEmpty()) dims.push_back(strId);
             SuperClassWriter::addVariable(axisid, typePrec, dims);
 
@@ -1104,11 +1108,12 @@
                 CArray<double,1> axis_value(zoom_size_srv);
                 for (int i = 0; i < zoom_size_srv; i++) axis_value(i) = axis->value_srv(i);
-                SuperClassWriter::writeData(axis_value, axisid, isCollective, 0);
-
-                if (!axis->bounds.isEmpty())
+                if (axis->label.isEmpty())  SuperClassWriter::writeData(axis_value, axisid, isCollective, 0);
+
+                if (!axis->bounds.isEmpty() && axis->label.isEmpty())
                   SuperClassWriter::writeData(axis->bound_srv, axisBoundsId, isCollective, 0);
 
+                if (! axis->label.isEmpty())  SuperClassWriter::writeData(axis->label_srv, axisid, isCollective, 0);
+ 
                 SuperClassWriter::definition_start();
-
                 break;
               }
@@ -1124,8 +1129,10 @@
                 startBounds[1] = 0;
                 countBounds[1] = 2;
-                SuperClassWriter::writeData(axis_value, axisid, isCollective, 0, &start, &count);
-
-                if (!axis->bounds.isEmpty())
+                if (axis->label.isEmpty()) SuperClassWriter::writeData(axis_value, axisid, isCollective, 0, &start, &count);
+
+                if (!axis->bounds.isEmpty()&& axis->label.isEmpty())
                   SuperClassWriter::writeData(axis->bound_srv, axisBoundsId, isCollective, 0, &startBounds, &countBounds);
+
+                if (! axis->label.isEmpty())  SuperClassWriter::writeData(axis->label_srv, axisid, isCollective, 0);
 
                 SuperClassWriter::definition_start();
Index: XIOS/trunk/src/io/netCdfInterface.cpp
===================================================================
--- XIOS/trunk/src/io/netCdfInterface.cpp	(revision 1049)
+++ XIOS/trunk/src/io/netCdfInterface.cpp	(revision 1050)
@@ -967,4 +967,10 @@
 }
 
+template<>
+int CNetCdfInterface::ncGetVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, char* data)
+{
+  return nc_get_vara_text(ncid, varid, start, count, data);
+}
+
 // Some specializations of putVariableType
 template<>
@@ -984,4 +990,10 @@
 {
   return nc_put_vara_int(ncid, varid, start, count, data);
+}
+
+template<>
+int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const char* data)
+{
+  return nc_put_vara_text(ncid, varid, start, count, data);
 }
 
Index: XIOS/trunk/src/io/netCdfInterface_decl.cpp
===================================================================
--- XIOS/trunk/src/io/netCdfInterface_decl.cpp	(revision 1049)
+++ XIOS/trunk/src/io/netCdfInterface_decl.cpp	(revision 1050)
@@ -33,5 +33,6 @@
   macroPutVar(float)
   macroPutVar(int)
-
+  macroPutVar(char)
+  
 #define macroType(type, ncType) \
   template<> nc_type CNetCdfInterface::getNcType<type>() { return ncType; }
Index: XIOS/trunk/src/io/onetcdf4.cpp
===================================================================
--- XIOS/trunk/src/io/onetcdf4.cpp	(revision 1049)
+++ XIOS/trunk/src/io/onetcdf4.cpp	(revision 1050)
@@ -503,9 +503,17 @@
       void CONetCDF4::writeData_(int grpid, int varid,
                                  const std::vector<StdSize>& sstart,
+                                 const std::vector<StdSize>& scount, char* data)
+      {
+          CNetCdfInterface::putVaraType(grpid, varid, &sstart[0], &scount[0], data);
+      }
+      
+      template <>
+
+      void CONetCDF4::writeData_(int grpid, int varid,
+                                 const std::vector<StdSize>& sstart,
                                  const std::vector<StdSize>& scount, const int* data)
       {
           CNetCdfInterface::putVaraType(grpid, varid, &sstart[0], &scount[0], data);
       }
-
       //---------------------------------------------------------------
 
Index: XIOS/trunk/src/io/onetcdf4_decl.cpp
===================================================================
--- XIOS/trunk/src/io/onetcdf4_decl.cpp	(revision 1049)
+++ XIOS/trunk/src/io/onetcdf4_decl.cpp	(revision 1050)
@@ -14,4 +14,5 @@
   macro(double, 2)
   macro(double, 3)
+  macro(StdString, 1)
  
   template void CONetCDF4::setDefaultValue<double>(const StdString & varname, const double* value) ;
Index: XIOS/trunk/src/io/onetcdf4_impl.hpp
===================================================================
--- XIOS/trunk/src/io/onetcdf4_impl.hpp	(revision 1049)
+++ XIOS/trunk/src/io/onetcdf4_impl.hpp	(revision 1050)
@@ -36,4 +36,42 @@
   }
 
+  template <>
+  void CONetCDF4::writeData(const CArray<StdString, 1>& data, const StdString & name,
+                            bool collective, StdSize record,
+                            const std::vector<StdSize> * start,
+                            const std::vector<StdSize> * count)
+  {
+    int grpid = this->getCurrentGroup();
+    int varid = this->getVariable(name);
+    StdSize array_size = 1;
+    std::vector<StdSize> sstart, scount;
+
+    if (this->wmpi && collective)
+    CNetCdfInterface::varParAccess(grpid, varid, NC_COLLECTIVE);
+    if (this->wmpi && !collective)
+    CNetCdfInterface::varParAccess(grpid, varid, NC_INDEPENDENT);
+
+    this->getWriteDataInfos
+    (name, record, array_size,  sstart, scount, start, count);
+    if (data.numElements()*stringArrayLen != array_size)
+    {
+      ERROR("CONetCDF4::writeData(...)",
+      << "[ input array size = "  << data.numElements()
+      << ", intern array size = " << array_size
+      << " ] Invalid input data !" );
+    }
+    char* ArrayStr ;
+    char *PtrArrayStr ;
+    PtrArrayStr=ArrayStr=new char[data.numElements()*stringArrayLen] ;
+    Array<StdString,1>::const_iterator it, itb=data.begin(), ite=data.end() ;
+    for(it=itb;it!=ite;++it,PtrArrayStr+=stringArrayLen)
+    {
+      it->copy(PtrArrayStr,it->size()) ;
+      PtrArrayStr[it->size()]='\0' ;
+    }
+    this->writeData_(grpid, varid, sstart, scount, ArrayStr);
+    delete [] ArrayStr ;
+  }
+
 //----------------------------------------------------------------
 
Index: XIOS/trunk/src/node/axis.cpp
===================================================================
--- XIOS/trunk/src/node/axis.cpp	(revision 1049)
+++ XIOS/trunk/src/node/axis.cpp	(revision 1050)
@@ -27,5 +27,5 @@
       , isDistributed_(false), hasBounds_(false), isCompressible_(false)
       , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
-      , transformationMap_(), hasValue(false)
+      , transformationMap_(), hasValue(false), hasLabel(false)
    {
    }
@@ -37,5 +37,5 @@
       , isDistributed_(false), hasBounds_(false), isCompressible_(false)
       , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
-      , transformationMap_(), hasValue(false)
+      , transformationMap_(), hasValue(false), hasLabel(false)
    {
    }
@@ -176,4 +176,7 @@
          if (hasBounds_)
            sizeValEvent += CArray<double,2>::size(2 * it->second.size());
+ 
+         if (hasLabel)
+           sizeValEvent += CArray<StdString,1>::size(it->second.size());
 
          size_t size = CEventClient::headerSize + getId().size() + sizeof(size_t) + std::max(sizeIndexEvent, sizeValEvent);
@@ -261,4 +264,5 @@
       this->checkMask();
       this->checkBounds();
+      this->checkLabel();
 
       isDistributed_ = (!this->begin.isEmpty() && !this->n.isEmpty() && (this->begin + this->n < this->n_glo)) ||
@@ -333,4 +337,17 @@
   }
 
+  void CAxis::checkLabel()
+  {
+    if (!label.isEmpty())
+    {
+      if (label.extent(0) != n)
+        ERROR("CAxis::checkLabel(void)",
+              << "The label array of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be of dimension of axis size." << std::endl
+              << "Axis size is " << n.getValue() << "." << std::endl
+              << "label size is "<< label.extent(0)<<  " .");
+      hasLabel = true;
+    }
+    else hasLabel = false;
+  }
   void CAxis::checkEligibilityForCompressedOutput()
   {
@@ -657,4 +674,5 @@
     list<CArray<double,1> > list_val;
     list<CArray<double,2> > list_bounds;
+    list<CArray<StdString,1> > list_label;
 
     std::map<int, std::vector<size_t> >::const_iterator it, iteMap;
@@ -675,4 +693,9 @@
         list_bounds.push_back(CArray<double,2>(2,nbData));
       }
+      
+      if (hasLabel)
+      {
+        list_label.push_back(CArray<StdString,1>(nbData));
+      }
 
       CArray<int,1>& indi = list_indi.back();
@@ -693,4 +716,10 @@
           boundsVal(1, n) = bounds(1,n);
         }
+        
+        if (hasLabel)
+        {
+          CArray<StdString,1>& labelVal = list_label.back();
+          labelVal(n) = label(n);
+        }
       }
 
@@ -716,4 +745,9 @@
       {
         list_msgsVal.back() << list_bounds.back();
+      }
+ 
+      if (hasLabel)
+      {
+        list_msgsVal.back() << list_label.back();
       }
 
@@ -783,7 +817,9 @@
     CArray<double,1> val;
     CArray<double,2> boundsVal;
+    CArray<StdString,1> labelVal;
 
     buffer >> val;
     if (hasBounds_) buffer >> boundsVal;
+    if (hasLabel) buffer >> labelVal;
 
     int i, j, ind_srv;
@@ -798,4 +834,10 @@
         bound_srv(1,ind_srv) = boundsVal(1, ind);
       }
+
+      if (hasLabel)
+      {
+        label_srv(ind_srv) = labelVal( ind);
+      }
+
     }
   }
@@ -836,4 +878,8 @@
         bound_srv(0,ind) = bounds(0,ind);
         bound_srv(1,ind) = bounds(1,ind);
+      }
+      if (hasLabel)
+      {
+        label_srv(ind) = label(ind);
       }
     }
@@ -927,4 +973,5 @@
       value_srv.resize(zoom_size_srv);
       if (hasBounds_)  bound_srv.resize(2,zoom_size_srv);
+      if (hasLabel)  label_srv.resize(zoom_size_srv);
     }
   }
Index: XIOS/trunk/src/node/axis.hpp
===================================================================
--- XIOS/trunk/src/node/axis.hpp	(revision 1049)
+++ XIOS/trunk/src/node/axis.hpp	(revision 1050)
@@ -123,4 +123,5 @@
         CArray<double,1> value_srv;
         CArray<double,2> bound_srv;
+        CArray<StdString,1> label_srv;
         bool hasValue;
 
@@ -130,4 +131,5 @@
          void checkZoom();
          void checkBounds();
+         void checkLabel();
          void checkTransformations();
          void sendValue();
@@ -163,4 +165,5 @@
          std::map<int, CArray<int,1> > indiSrv_;
          bool hasBounds_;
+         bool hasLabel;
 
        private:
