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

Last change on this file since 680 was 680, checked in by rlacroix, 9 years ago

Rephrase some error messages so that they are clearer.

  • 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: 6.4 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 
253  template <typename T>
254  CBufferOut& operator<<(CBufferOut& buffer, const CEnum<T>& type)
255  {
256    if (!type.toBuffer(buffer)) ERROR("template <typename T> CBufferOut& operator<<(CBufferOut& buffer, const CEnum<T>& type)",
257                                      << "Not enough free space in buffer to queue the enum.");
258    return buffer ;
259  }
260
261  template <typename T>
262  CBufferOut& operator<<(CBufferOut& buffer, const typename T::t_enum & type)
263  {
264    if (!CEnum<T>(type).toBuffer(buffer)) ERROR("template <typename T> CBufferOut& operator<<(CBufferOut& buffer, const typename T::t_enum & type)",
265                                                << "Not enough free space in buffer to queue the enum.");
266    return buffer ;
267  }
268 
269  template <typename T>
270  CBufferIn& operator>>(CBufferIn& buffer, CEnum<T>& type)
271  {
272    if (!type.fromBuffer(buffer)) ERROR("template <typename T> CBufferIn& operator>>(CBufferIn& buffer, CEnum<T>& type)",
273                                        << "Not enough data in buffer to unqueue the enum.");
274    return buffer ;
275  }
276 
277/*
278  template <typename T>
279  CMessage& operator<<(CMessage& msg, const CEnum<T>& type)
280  {
281    msg.push(*type.clone()) ;
282    return msg ;
283  }
284*/
285
286  template <typename T>
287  CMessage& operator<<(CMessage& msg, const typename T::t_enum & type)
288  {
289    msg.push(*CEnum<T>(type).clone()) ;
290    return msg ;
291  }
292 
293}
294
295#endif
296
Note: See TracBrowser for help on using the repository browser.