source: XIOS/trunk/src/type/enum_impl.hpp @ 369

Last change on this file since 369 was 369, checked in by ymipsl, 12 years ago

Major Update

  • redesign Type and attribute manipulation
  • add enumerate type and attribute
  • use blitz class array instead of boost class array

YM

File size: 6.4 KB
Line 
1#ifndef __XIOS_ENUM_IMPL__
2#define __XIOS_ENUM_IMPL__
3
4#include "xmlioserver_spl.hpp"
5#include "exception.hpp"
6#include "buffer_in.hpp"
7#include "buffer_out.hpp"
8#include "message.hpp"
9#include <string>
10#include <boost/algorithm/string.hpp>
11
12namespace xios
13{
14 
15  using namespace std;
16 
17  template <typename T>
18  CEnum<T>::CEnum(void)
19  {
20    empty=true ;
21  }
22   
23  template <typename T>
24  CEnum<T>::CEnum(const T_enum& val)
25  {
26    empty=true ;
27    set(val) ;
28  }
29 
30  template <typename T>
31  CEnum<T>::CEnum(const CEnum<T>& type)
32  {
33    empty=true ;
34    set(type) ;
35  }
36
37  template <typename T>
38  CEnum<T>::CEnum(const CEnum_ref<T>& type)
39  {
40    empty=true ;
41    set(type) ;
42  } 
43
44  template <typename T>
45  void CEnum<T>::set(const T_enum& val)
46  {
47    if (empty) 
48    { 
49      ptrValue = new T_enum(val) ;
50      empty=false ;
51    }
52    else *ptrValue = val ;
53  }
54
55  template <typename T>
56  void CEnum<T>::set(const CEnum<T>& type)
57  {
58    if (type.isEmpty()) reset() ;
59    else
60    {
61      if (empty)
62      { 
63        ptrValue = new T_enum(*type.ptrValue) ;
64        empty=false ;
65      }
66      else *ptrValue = *type.ptrValue ;
67    }
68  }
69
70  template <typename T>
71  void CEnum<T>::set(const CEnum_ref<T>& type)
72  {
73    if (type.isEmpty()) reset() ;
74    else
75    {
76      if (empty)
77      { 
78        ptrValue = new T_enum(*type.ptrValue) ;
79        empty=false ;
80      }
81      else *ptrValue = *type.ptrValue ;
82    }
83  }
84
85
86  template <typename T>
87  typename T::t_enum & CEnum<T>::get(void)
88  {
89    checkEmpty();
90    return *ptrValue ;
91  }
92
93  template <typename T>
94  const typename T::t_enum& CEnum<T>::get(void) const
95  {
96    checkEmpty();
97    return *ptrValue ;
98  }
99 
100  template <typename T>
101  CEnum<T>& CEnum<T>::operator = (const T_enum& val)
102  {
103    set(val) ;
104    return *this ;
105  }
106 
107  template <typename T>
108  CEnum<T>& CEnum<T>::operator = (const CEnum<T>& type)
109  {
110    set(type) ;
111    return *this ;
112  }
113
114  template <typename T>
115  CEnum<T>& CEnum<T>::operator = (const CEnum_ref<T>& type)
116  {
117    set(type) ;
118    return *this ;
119  }
120
121
122  template <typename T>
123  CEnum<T>::operator T_enum&()
124  {
125    cout<<"CEnum<T>::operator T_enum&()"<<endl ;
126    checkEmpty();
127    return *ptrValue ;
128   }
129
130   template <typename T>
131   CEnum<T>* CEnum<T>::_clone(void) const
132   {
133     checkEmpty();
134     return new CEnum(*this) ;
135   }
136
137 
138  template <class T>
139  void CEnum<T>::_fromString(const string& str)
140  {
141    string tmpStr=boost::to_lower_copy(boost::trim_copy(str)) ;
142   
143    bool found=false ;
144    for(int i=0;i<T::getSize();i++)
145    {
146      if (boost::to_lower_copy(string(T::getStr()[i]))==tmpStr)
147      {
148        allocate() ;
149        *ptrValue=(T_enum) i ;
150        return ;
151      }
152    }
153   
154    ostringstream strList ;
155    for(int i=0;i<T::getSize();i++) 
156    {
157      if (i>0) strList<<", " ;
158      strList<<boost::to_lower_copy(string(T::getStr()[i])) ;
159    }
160   
161    ERROR("template <typename T> void CEnum<T>::_fromString(const string& str)",
162    << tmpStr << " cannot be converted in a valid enumeration, possibilities are : "<<strList.str() ) ;
163
164  }
165
166  template <typename T>
167  size_t CEnum<T>::_size(void) const
168  {
169    return sizeof(T_enum) ;
170  }
171 
172  template <typename T>
173  bool CEnum<T>::_isEmpty(void) const
174  {
175    return empty ;
176  }
177 
178  template <typename T>
179  string CEnum<T>::_toString(void) const
180  {
181    if (!empty) return string((T::getStr())[(int)(*ptrValue)]) ;
182  }
183 
184  template <typename T>
185  bool CEnum<T>::_toBuffer(CBufferOut& buffer) const
186  {
187    checkEmpty();
188    if (sizeof(*ptrValue)==sizeof(short int)) return buffer.put((short int) *ptrValue) ;
189    else if (sizeof(*ptrValue)==sizeof(int)) return buffer.put((int) *ptrValue) ;
190    else if (sizeof(*ptrValue)==sizeof(long int)) return buffer.put((long int) *ptrValue) ;
191    else ERROR("template <typename T>  bool CEnum<T>::_toBuffer(CBufferOut& buffer) const",
192               <<"incompatibility between enumeration and standard integer type") ;
193  }
194 
195  template <typename T>
196  bool CEnum<T>::_fromBuffer(CBufferIn& buffer)
197  {
198    bool ret ;
199    allocate() ;
200    if (sizeof(*ptrValue)==sizeof(short int)) 
201    {
202      short int val ;
203      ret=buffer.get(val) ;
204      if (ret) *ptrValue = (T_enum) val ;
205    }
206    else if (sizeof(*ptrValue)==sizeof(int)) 
207    {
208      int val ;
209      ret=buffer.get(val) ;
210      if (ret) *ptrValue = (T_enum) val ;
211    }
212    else if (sizeof(*ptrValue)==sizeof(long int)) 
213    {
214      long int val ;
215      ret=buffer.get(val) ;
216      if (ret) *ptrValue = (T_enum) val ;
217    }
218    else ERROR("template <typename T>  bool CEnum<T>::_fromBuffer(CBufferIn& buffer)",
219               <<"incompatibility between enumeration and standard integer type") ;
220    return ret ;
221  }
222 
223
224  template <typename T>
225  void CEnum<T>::allocate(void)
226  {
227    if (empty) 
228    {
229      ptrValue = new T_enum ;
230      empty=false ;
231    }
232  }
233 
234  template <typename T>
235  void CEnum<T>::_reset(void)
236  {
237    if (!empty) 
238    {
239      delete ptrValue ;
240      empty=true ;
241    }
242  }
243 
244  template <typename T>
245  void CEnum<T>::checkEmpty(void) const
246  {
247    if (empty) ERROR("template <typename T> void CEnum<T>::checkEmpty(void) const", <<"Type is not initialized") ;
248  } 
249
250 
251  template <typename T>
252  CBufferOut& operator<<(CBufferOut& buffer, const CEnum<T>& type)
253  {
254    if (!type.toBuffer(buffer)) ERROR("template <typename T> CBufferOut& operator<<(CBufferOut& buffer, const CEnum<T>& type)",
255                                           <<"Buffer remain size is to low for size type") ;
256    return buffer ;
257  }
258
259  template <typename T>
260  CBufferOut& operator<<(CBufferOut& buffer, const typename T::t_enum & type)
261  {
262    if (!CEnum<T>(type).toBuffer(buffer)) ERROR("template <typename T> CBufferOut& operator<<(CBufferOut& buffer, const typename T::t_enum & type)",
263                                           <<"Buffer remain size is to low for size type") ;     
264    return buffer ;
265  }
266 
267  template <typename T>
268  CBufferIn& operator>>(CBufferIn& buffer, CEnum<T>& type)
269  {
270    if (! type.fromBuffer(buffer)) ERROR("template <typename T> CBufferIn& operator>>(CBufferIn& buffer, CEnum<T>& type)",
271                                           <<"Buffer remain size is to low for size type") ;
272    return buffer ;
273  }
274 
275 
276  template <typename T>
277  CMessage& operator<<(CMessage& msg, const CEnum<T>& type)
278  {
279    msg.push(*type.clone()) ;
280    return msg ;
281  }
282
283  template <typename T>
284  CMessage& operator<<(CMessage& msg, const typename T::t_enum & type)
285  {
286    msg.push(*CEnum<T>(type).clone()) ;
287    return msg ;
288  }
289 
290}
291
292#endif
293
Note: See TracBrowser for help on using the repository browser.