source: XIOS/dev/dev_olga/src/type/enum_impl.hpp @ 1158

Last change on this file since 1158 was 1158, checked in by oabramkina, 7 years ago

Two server levels: merging with trunk r1137.
There are bugs.

  • Property copyright set to
    Software name : XIOS (Xml I/O Server)
    http://forge.ipsl.jussieu.fr/ioserver
    Creation date : January 2009
    Licence : CeCCIL version2
    see license file in root directory : Licence_CeCILL_V2-en.txt
    or http://www.cecill.info/licences/Licence_CeCILL_V2-en.html
    Holder : CEA/LSCE (Laboratoire des Sciences du CLimat et de l'Environnement)
    CNRS/IPSL (Institut Pierre Simon Laplace)
    Project Manager : Yann Meurdesoif
    yann.meurdesoif@cea.fr
File size: 7.0 KB
Line 
1#ifndef __XIOS_ENUM_IMPL__
2#define __XIOS_ENUM_IMPL__
3
4#include "xios_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    checkEmpty();
126    return *ptrValue ;
127   }
128
129   template <typename T>
130   CEnum<T>* CEnum<T>::_clone(void) const
131   {
132     checkEmpty();
133     return new CEnum(*this) ;
134   }
135
136 
137  template <class T>
138  void CEnum<T>::_fromString(const string& str)
139  {
140    string tmpStr=boost::to_lower_copy(boost::trim_copy(str)) ;
141   
142    bool found=false ;
143    for(int i=0;i<T::getSize();i++)
144    {
145      if (boost::to_lower_copy(string(T::getStr()[i]))==tmpStr)
146      {
147        allocate() ;
148        *ptrValue=(T_enum) i ;
149        return ;
150      }
151    }
152   
153    ostringstream strList ;
154    for(int i=0;i<T::getSize();i++) 
155    {
156      if (i>0) strList<<", " ;
157      strList<<boost::to_lower_copy(string(T::getStr()[i])) ;
158    }
159   
160    ERROR("template <typename T> void CEnum<T>::_fromString(const string& str)",
161          << tmpStr << " cannot be converted in a valid enumeration, possibilities are: " << strList.str());
162
163  }
164
165  template <typename T>
166  size_t CEnum<T>::_size(void) const
167  {
168    return sizeof(T_enum) ;
169  }
170 
171  template <typename T>
172  bool CEnum<T>::_isEmpty(void) const
173  {
174    return empty ;
175  }
176 
177  template <typename T>
178  string CEnum<T>::_toString(void) const
179  {
180    if (empty) return string("empty") ;
181    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    return false ;
194  }
195 
196  template <typename T>
197  bool CEnum<T>::_fromBuffer(CBufferIn& buffer)
198  {
199    bool ret ;
200    allocate() ;
201    if (sizeof(*ptrValue)==sizeof(short int)) 
202    {
203      short int val ;
204      ret=buffer.get(val) ;
205      if (ret) *ptrValue = (T_enum) val ;
206    }
207    else if (sizeof(*ptrValue)==sizeof(int)) 
208    {
209      int val ;
210      ret=buffer.get(val) ;
211      if (ret) *ptrValue = (T_enum) val ;
212    }
213    else if (sizeof(*ptrValue)==sizeof(long int)) 
214    {
215      long int val ;
216      ret=buffer.get(val) ;
217      if (ret) *ptrValue = (T_enum) val ;
218    }
219    else ERROR("template <typename T> bool CEnum<T>::_fromBuffer(CBufferIn& buffer)",
220               << "incompatibility between enumeration and standard integer type.");
221    return ret ;
222  }
223 
224
225  template <typename T>
226  void CEnum<T>::allocate(void)
227  {
228    if (empty) 
229    {
230      ptrValue = new T_enum ;
231      empty=false ;
232    }
233  }
234 
235  template <typename T>
236  void CEnum<T>::_reset(void)
237  {
238    if (!empty) 
239    {
240      delete ptrValue ;
241      empty=true ;
242    }
243  }
244 
245  template <typename T>
246  void CEnum<T>::checkEmpty(void) const
247  {
248    if (empty) ERROR("template <typename T> void CEnum<T>::checkEmpty(void) const",
249                     << "Enum is not initialized.");
250  } 
251 
252  template <typename T> 
253  bool operator== (const CEnum<T>& lhs, const typename T::t_enum& rhs)
254  {
255     if (lhs.isEmpty()) return false;
256     return (lhs.get() == rhs);
257  }
258
259  template <typename T> 
260  bool operator== (const typename T::t_enum& lhs, const CEnum<T>& rhs)
261  {
262    return rhs == lhs;
263  }
264
265  template <typename T> 
266  bool operator== (const CEnum<T>& lhs, const CEnum<T>& rhs)
267  {
268    if ((lhs.isEmpty() && !rhs.isEmpty()) || (!lhs.isEmpty() && rhs.isEmpty())) return false;
269    if (lhs.isEmpty() && rhs.isEmpty()) return true;
270    return (lhs.get() == rhs.get());
271  }
272
273
274  template <typename T>
275  CBufferOut& operator<<(CBufferOut& buffer, const CEnum<T>& type)
276  {
277    if (!type.toBuffer(buffer)) ERROR("template <typename T> CBufferOut& operator<<(CBufferOut& buffer, const CEnum<T>& type)",
278                                      << "Not enough free space in buffer to queue the enum.");
279    return buffer ;
280  }
281
282  template <typename T>
283  CBufferOut& operator<<(CBufferOut& buffer, const typename T::t_enum & type)
284  {
285    if (!CEnum<T>(type).toBuffer(buffer)) ERROR("template <typename T> CBufferOut& operator<<(CBufferOut& buffer, const typename T::t_enum & type)",
286                                                << "Not enough free space in buffer to queue the enum.");
287    return buffer ;
288  }
289 
290  template <typename T>
291  CBufferIn& operator>>(CBufferIn& buffer, CEnum<T>& type)
292  {
293    if (!type.fromBuffer(buffer)) ERROR("template <typename T> CBufferIn& operator>>(CBufferIn& buffer, CEnum<T>& type)",
294                                        << "Not enough data in buffer to unqueue the enum.");
295    return buffer ;
296  }
297 
298/*
299  template <typename T>
300  CMessage& operator<<(CMessage& msg, const CEnum<T>& type)
301  {
302    msg.push(*type.clone()) ;
303    return msg ;
304  }
305*/
306
307  template <typename T>
308  CMessage& operator<<(CMessage& msg, const typename T::t_enum & type)
309  {
310    msg.push(*CEnum<T>(type).clone()) ;
311    return msg ;
312  }
313 
314}
315
316#endif
317
Note: See TracBrowser for help on using the repository browser.