(file) Return to Message.h CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

  1 karl  1.72 //%2006////////////////////////////////////////////////////////////////////////
  2 mike  1.4  //
  3 karl  1.58 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  4            // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  5            // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  6 karl  1.48 // IBM Corp.; EMC Corporation, The Open Group.
  7 karl  1.58 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8            // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9 karl  1.62 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10            // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11 karl  1.72 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12            // EMC Corporation; Symantec Corporation; The Open Group.
 13 mike  1.4  //
 14            // Permission is hereby granted, free of charge, to any person obtaining a copy
 15 chip  1.24 // of this software and associated documentation files (the "Software"), to
 16            // deal in the Software without restriction, including without limitation the
 17            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 18 mike  1.4  // sell copies of the Software, and to permit persons to whom the Software is
 19            // furnished to do so, subject to the following conditions:
 20 kumpf 1.37 // 
 21 chip  1.24 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22 mike  1.4  // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 23            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 24 chip  1.24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 25            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 26            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 27 mike  1.4  // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 28            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 29            //
 30            //==============================================================================
 31            //
 32            //%/////////////////////////////////////////////////////////////////////////////
 33            
 34            #ifndef Pegasus_Message_h
 35            #define Pegasus_Message_h
 36            
 37 mike  1.6  #include <Pegasus/Common/Config.h>
 38 mike  1.4  #include <iostream>
 39 mike  1.6  #include <cstring>
 40 kumpf 1.39 #include <Pegasus/Common/InternalException.h>
 41 kumpf 1.38 #include <Pegasus/Common/Linkage.h>
 42 w.white 1.68 #include <Pegasus/Common/TimeValue.h>
 43 w.white 1.63 #include <Pegasus/Common/CIMOperationType.h>
 44 kumpf   1.81 #include <Pegasus/Common/Threads.h>
 45 mike    1.76 #include <Pegasus/Common/Linkable.h>
 46 mike    1.4  
 47              PEGASUS_NAMESPACE_BEGIN
 48              
 49 kumpf   1.83 class PEGASUS_COMMON_LINKAGE MessageMask
 50 mike    1.6  {
 51 kumpf   1.83 public:
 52                  // Message type is indicated by the low order 20 bits.  For example:
 53                  // Uint32 messageType = flags & 0x000fffff;
 54                  static Uint32 type_legacy;
 55                  static Uint32 type_cimom;
 56                  static Uint32 type_service;
 57              
 58                  // Message handling is indicated by the high order 12 bits.  For example:
 59                  // Uint32 messageHandling = flags & 0xfff00000;
 60                  static Uint32 ha_request;
 61                  static Uint32 ha_reply;
 62                  static Uint32 ha_async;
 63 mike    1.6  };
 64              
 65 kumpf   1.40 enum HttpMethod
 66              {
 67                  HTTP_METHOD__POST,
 68                  HTTP_METHOD_M_POST
 69              };
 70              
 71 chip    1.24 /** The Message class and derived classes are used to pass messages between
 72 mike    1.4      modules. Messages are passed between modules using the message queues
 73                  (see MessageQueue class). Derived classes may add their own fields.
 74 kumpf   1.78     This base class defines a common type field, which is the type of
 75                  the message.
 76 mike    1.4  */
 77 mike    1.76 class PEGASUS_COMMON_LINKAGE Message : public Linkable
 78 mike    1.4  {
 79 kumpf   1.86 public:
 80              
 81                  Message(
 82                      Uint32 type,
 83                      Uint32 destination = 0,
 84                      Uint32 mask = MessageMask::type_legacy)
 85                      :
 86                      _type(type),
 87                      _mask(mask),
 88                      _httpMethod (HTTP_METHOD__POST),
 89 venkat.puvvada 1.87 #ifndef PEGASUS_DISABLE_PERFINST
 90 kumpf          1.86         _serverStartTimeMicroseconds(0),
 91                             _providerTimeMicroseconds(0),
 92                             _totalServerTimeMicroseconds(0),
 93 venkat.puvvada 1.87 #endif
 94 kumpf          1.86         _close_connect(false),
 95                             _last_thread_id(Threads::self()),
 96                             _async(0),
 97                             dest(destination),
 98                             _isComplete(true),
 99                             _index(0)
100                         {
101                         }
102 mike           1.4  
103 kumpf          1.86     virtual ~Message();
104 chip           1.24 
105 kumpf          1.86     // NOTE: The compiler default implementation of the copy constructor
106                         // is used for this class.
107                     
108                         Boolean getCloseConnect() const { return _close_connect; }
109                         void setCloseConnect(Boolean close_connect)
110                         {
111                             _close_connect = close_connect;
112                         }
113 chip           1.24 
114 kumpf          1.86     Uint32 getType() const { return _type; }
115 kumpf          1.40 
116 kumpf          1.86     void setType(Uint32 type) { _type = type; }
117                     
118                         Uint32 getMask() const { return _mask; }
119                     
120                         void setMask(Uint32 mask) { _mask = mask; }
121                     
122                         HttpMethod getHttpMethod() const { return _httpMethod; }
123                     
124                         void setHttpMethod(HttpMethod httpMethod) {_httpMethod = httpMethod;}
125 kumpf          1.40 
126 karl           1.61 #ifndef PEGASUS_DISABLE_PERFINST
127 kumpf          1.86     //
128                         // Needed for performance measurement
129                         //
130                     
131                         Uint64 getServerStartTime() const
132                         {
133                             return _serverStartTimeMicroseconds;
134                         }
135                     
136                         void setServerStartTime(Uint64 serverStartTimeMicroseconds)
137                         {
138                              _serverStartTimeMicroseconds = serverStartTimeMicroseconds;
139                         }
140                     
141                         void endServer();
142                     
143                         Uint64 getProviderTime() const
144                         {
145                             return _providerTimeMicroseconds;
146                         }
147                     
148 kumpf          1.86     void setProviderTime(Uint64 providerTimeMicroseconds)
149                         {
150                             _providerTimeMicroseconds = providerTimeMicroseconds;
151                         }
152                     
153                         Uint64 getTotalServerTime() const
154                         {
155                             return _totalServerTimeMicroseconds;
156                         }
157                     
158                         void setTotalServerTime(Uint64 totalServerTimeMicroseconds)
159                         {
160                             _totalServerTimeMicroseconds = totalServerTimeMicroseconds;
161                         }
162 sage           1.30 
163 sage           1.31 #endif
164 sage           1.30 
165 kumpf          1.86     static CIMOperationType convertMessageTypetoCIMOpType(Uint32 type);
166 w.white        1.63 
167 joyce.j        1.69 #ifdef PEGASUS_DEBUG
168 kumpf          1.86     virtual void print(
169                             PEGASUS_STD(ostream)& os,
170                             Boolean printHeader = true) const;
171 joyce.j        1.69 #endif
172 mike           1.4  
173 kumpf          1.86     Message* get_async()
174                         {
175                             Message *ret = _async;
176                             _async = 0;
177                             return ret;
178                         }
179                     
180                         void put_async(Message* msg)
181                         {
182                             _async = msg;
183                         }
184                     
185                         // << Tue Jul  1 11:02:49 2003 mdd >> pep_88 and helper for i18n and l10n
186                         Boolean thread_changed()
187                         {
188                             if (!Threads::equal(_last_thread_id, Threads::self()))
189                             {
190                                 _last_thread_id = Threads::self();
191                                 return true;
192                             }
193                     
194 kumpf          1.86         return false;
195                         }
196                     
197                         // set the message index indicating what piece (or sequence) this is
198                         // message indexes start at zero
199                         void setIndex(Uint32 index) { _index = index; }
200                     
201                         // increment the message index
202                         void incrementIndex() { _index++; }
203                     
204                         // set the complete flag indicating if this message piece is the
205                         // last or not
206                         void setComplete(Boolean isComplete)
207                         {
208                             _isComplete = isComplete ? true:false;
209                         }
210                     
211                         // get the message index (or sequence number)
212                         Uint32 getIndex() const { return _index; }
213 w.white        1.56 
214 kumpf          1.86     // is this the first piece of the message ?
215                         Boolean isFirst() const { return _index == 0 ? true : false; }
216                     
217                         // is this message complete? (i.e the last in a one or more sequence)
218                         Boolean isComplete() const { return _isComplete; }
219                     
220                     private:
221                         Uint32 _type;
222                         Uint32 _mask;
223                         HttpMethod _httpMethod;
224                     
225 venkat.puvvada 1.87 #ifndef PEGASUS_DISABLE_PERFINST
226 kumpf          1.86     // Needed for performance measurement
227                         Uint64 _serverStartTimeMicroseconds;
228                         Uint64 _providerTimeMicroseconds;
229                         Uint64 _totalServerTimeMicroseconds;
230 venkat.puvvada 1.87 #endif
231 kumpf          1.86     Boolean _close_connect;
232                     
233                         // << Tue Jul  1 11:02:35 2003 mdd >> pep_88 and helper for i18n and l10n
234                         ThreadType _last_thread_id;
235                     
236                     public:
237                         Message *_async;
238                         Uint32 dest;
239                     
240                     private:
241                         Message& operator=(const Message& msg);
242 kumpf          1.85 
243 kumpf          1.86     Boolean _isComplete;
244                         Uint32 _index;
245 mike           1.4  };
246 mike           1.5  
247 mike           1.6  
248 mike           1.5  enum MessageType
249                     {
250                         DUMMY_MESSAGE,
251                     
252                         // CIM Message types:
253                     
254                         CIM_GET_CLASS_REQUEST_MESSAGE,
255                         CIM_GET_INSTANCE_REQUEST_MESSAGE,
256 mike           1.6      CIM_EXPORT_INDICATION_REQUEST_MESSAGE,
257 mike           1.5      CIM_DELETE_CLASS_REQUEST_MESSAGE,
258                         CIM_DELETE_INSTANCE_REQUEST_MESSAGE,
259                         CIM_CREATE_CLASS_REQUEST_MESSAGE,
260                         CIM_CREATE_INSTANCE_REQUEST_MESSAGE,
261                         CIM_MODIFY_CLASS_REQUEST_MESSAGE,
262                         CIM_MODIFY_INSTANCE_REQUEST_MESSAGE,
263 mday           1.32     CIM_ENUMERATE_CLASSES_REQUEST_MESSAGE, //10
264 mike           1.5      CIM_ENUMERATE_CLASS_NAMES_REQUEST_MESSAGE,
265                         CIM_ENUMERATE_INSTANCES_REQUEST_MESSAGE,
266                         CIM_ENUMERATE_INSTANCE_NAMES_REQUEST_MESSAGE,
267                         CIM_EXEC_QUERY_REQUEST_MESSAGE,
268                         CIM_ASSOCIATORS_REQUEST_MESSAGE,
269                         CIM_ASSOCIATOR_NAMES_REQUEST_MESSAGE,
270                         CIM_REFERENCES_REQUEST_MESSAGE,
271                         CIM_REFERENCE_NAMES_REQUEST_MESSAGE,
272                         CIM_GET_PROPERTY_REQUEST_MESSAGE,
273 mday           1.32     CIM_SET_PROPERTY_REQUEST_MESSAGE, //20
274 mike           1.5      CIM_GET_QUALIFIER_REQUEST_MESSAGE,
275                         CIM_SET_QUALIFIER_REQUEST_MESSAGE,
276                         CIM_DELETE_QUALIFIER_REQUEST_MESSAGE,
277                         CIM_ENUMERATE_QUALIFIERS_REQUEST_MESSAGE,
278                         CIM_INVOKE_METHOD_REQUEST_MESSAGE,
279 kumpf          1.15     CIM_PROCESS_INDICATION_REQUEST_MESSAGE,
280 kumpf          1.73     CIM_HANDLE_INDICATION_REQUEST_MESSAGE,
281 kumpf          1.75     CIM_NOTIFY_PROVIDER_REGISTRATION_REQUEST_MESSAGE,
282 kumpf          1.15     CIM_NOTIFY_PROVIDER_TERMINATION_REQUEST_MESSAGE,
283 kumpf          1.75     CIM_CREATE_SUBSCRIPTION_REQUEST_MESSAGE,  // 30
284 chip           1.25     CIM_MODIFY_SUBSCRIPTION_REQUEST_MESSAGE,
285                         CIM_DELETE_SUBSCRIPTION_REQUEST_MESSAGE,
286 kumpf          1.29     CIM_DISABLE_MODULE_REQUEST_MESSAGE,
287                         CIM_ENABLE_MODULE_REQUEST_MESSAGE,
288 carolann.graves 1.64     CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE,
289 kumpf           1.35 
290 kumpf           1.43     CIM_GET_CLASS_RESPONSE_MESSAGE,
291 kumpf           1.73     CIM_GET_INSTANCE_RESPONSE_MESSAGE,
292 kumpf           1.75     CIM_EXPORT_INDICATION_RESPONSE_MESSAGE,
293 mike            1.5      CIM_DELETE_CLASS_RESPONSE_MESSAGE,
294 kumpf           1.75     CIM_DELETE_INSTANCE_RESPONSE_MESSAGE,  // 40
295 mike            1.5      CIM_CREATE_CLASS_RESPONSE_MESSAGE,
296                          CIM_CREATE_INSTANCE_RESPONSE_MESSAGE,
297                          CIM_MODIFY_CLASS_RESPONSE_MESSAGE,
298                          CIM_MODIFY_INSTANCE_RESPONSE_MESSAGE,
299 carolann.graves 1.64     CIM_ENUMERATE_CLASSES_RESPONSE_MESSAGE,
300 mike            1.5      CIM_ENUMERATE_CLASS_NAMES_RESPONSE_MESSAGE,
301 kumpf           1.73     CIM_ENUMERATE_INSTANCES_RESPONSE_MESSAGE,
302 kumpf           1.75     CIM_ENUMERATE_INSTANCE_NAMES_RESPONSE_MESSAGE,
303 mike            1.5      CIM_EXEC_QUERY_RESPONSE_MESSAGE,
304 kumpf           1.75     CIM_ASSOCIATORS_RESPONSE_MESSAGE,  // 50
305 mike            1.5      CIM_ASSOCIATOR_NAMES_RESPONSE_MESSAGE,
306                          CIM_REFERENCES_RESPONSE_MESSAGE,
307                          CIM_REFERENCE_NAMES_RESPONSE_MESSAGE,
308                          CIM_GET_PROPERTY_RESPONSE_MESSAGE,
309 carolann.graves 1.64     CIM_SET_PROPERTY_RESPONSE_MESSAGE,
310 mike            1.5      CIM_GET_QUALIFIER_RESPONSE_MESSAGE,
311 kumpf           1.73     CIM_SET_QUALIFIER_RESPONSE_MESSAGE,
312 kumpf           1.75     CIM_DELETE_QUALIFIER_RESPONSE_MESSAGE,
313 mike            1.5      CIM_ENUMERATE_QUALIFIERS_RESPONSE_MESSAGE,
314 kumpf           1.75     CIM_INVOKE_METHOD_RESPONSE_MESSAGE,  // 60
315 kumpf           1.15     CIM_PROCESS_INDICATION_RESPONSE_MESSAGE,
316 carolann.graves 1.64     CIM_NOTIFY_PROVIDER_REGISTRATION_RESPONSE_MESSAGE,
317 kumpf           1.15     CIM_NOTIFY_PROVIDER_TERMINATION_RESPONSE_MESSAGE,
318 kumpf           1.73     CIM_HANDLE_INDICATION_RESPONSE_MESSAGE,
319 chip            1.25     CIM_CREATE_SUBSCRIPTION_RESPONSE_MESSAGE,
320 kumpf           1.75     CIM_MODIFY_SUBSCRIPTION_RESPONSE_MESSAGE,
321 chip            1.25     CIM_DELETE_SUBSCRIPTION_RESPONSE_MESSAGE,
322 kumpf           1.29     CIM_DISABLE_MODULE_RESPONSE_MESSAGE,
323                          CIM_ENABLE_MODULE_RESPONSE_MESSAGE,
324 kumpf           1.75     CIM_STOP_ALL_PROVIDERS_RESPONSE_MESSAGE,  // 70
325 chip            1.24 
326 mike            1.6      // Monitor-related messages:
327                      
328                          SOCKET_MESSAGE,
329                      
330                          // Connection-oriented messages:
331                      
332                          CLOSE_CONNECTION_MESSAGE,
333                      
334                          // HTTP messages:
335                      
336                          HTTP_MESSAGE,
337 kumpf           1.73     HTTP_ERROR_MESSAGE,
338 kumpf           1.28 
339                          // Exception messages to be passed to a CIM client application:
340                      
341                          CLIENT_EXCEPTION_MESSAGE,
342 mike            1.5  
343 kumpf           1.75     ASYNC_REGISTER_CIM_SERVICE,
344 mday            1.33     ASYNC_DEREGISTER_CIM_SERVICE,
345                          ASYNC_UPDATE_CIM_SERVICE,
346                          ASYNC_IOCTL,
347 kumpf           1.75     ASYNC_CIMSERVICE_START,  // 80
348 mday            1.33     ASYNC_CIMSERVICE_STOP,
349                          ASYNC_CIMSERVICE_PAUSE,
350                          ASYNC_CIMSERVICE_RESUME,
351                      
352 kumpf           1.73     ASYNC_ASYNC_OP_START,
353 mday            1.33     ASYNC_ASYNC_OP_RESULT,
354 kumpf           1.75     ASYNC_ASYNC_LEGACY_OP_START,
355 chip            1.34     ASYNC_ASYNC_LEGACY_OP_RESULT,
356                      
357 mday            1.33     ASYNC_FIND_SERVICE_Q,
358                          ASYNC_FIND_SERVICE_Q_RESULT,
359 kumpf           1.75     ASYNC_ENUMERATE_SERVICE,  // 90
360 mday            1.33     ASYNC_ENUMERATE_SERVICE_RESULT,
361 chip            1.34 
362 mday            1.33     ASYNC_REGISTERED_MODULE,
363                          ASYNC_DEREGISTERED_MODULE,
364 kumpf           1.73     ASYNC_FIND_MODULE_IN_SERVICE,
365 mday            1.33     ASYNC_FIND_MODULE_IN_SERVICE_RESPONSE,
366 chip            1.34 
367 kumpf           1.75     ASYNC_ASYNC_MODULE_OP_START,
368 mday            1.33     ASYNC_ASYNC_MODULE_OP_RESULT,
369                      
370 kumpf           1.53     CIM_NOTIFY_PROVIDER_ENABLE_REQUEST_MESSAGE,
371                          CIM_NOTIFY_PROVIDER_ENABLE_RESPONSE_MESSAGE,
372                      
373 kumpf           1.75     CIM_NOTIFY_PROVIDER_FAIL_REQUEST_MESSAGE,  // 100
374 carolann.graves 1.74     CIM_NOTIFY_PROVIDER_FAIL_RESPONSE_MESSAGE,
375                      
376 kumpf           1.53     CIM_INITIALIZE_PROVIDER_REQUEST_MESSAGE,
377 w.white         1.52     CIM_INITIALIZE_PROVIDER_RESPONSE_MESSAGE,
378                      
379 kumpf           1.53     CIM_INITIALIZE_PROVIDER_AGENT_REQUEST_MESSAGE,
380                          CIM_INITIALIZE_PROVIDER_AGENT_RESPONSE_MESSAGE,
381 kumpf           1.47 
382 kumpf           1.54     CIM_NOTIFY_CONFIG_CHANGE_REQUEST_MESSAGE,
383                          CIM_NOTIFY_CONFIG_CHANGE_RESPONSE_MESSAGE,
384                      
385 carolann.graves 1.64     CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE,
386                          CIM_SUBSCRIPTION_INIT_COMPLETE_RESPONSE_MESSAGE,
387                      
388 mike            1.5      NUMBER_OF_MESSAGES
389                      };
390                      
391                      PEGASUS_COMMON_LINKAGE const char* MessageTypeToString(Uint32 messageType);
392 mike            1.6  
393                      /** This class implements a stack of queue-ids. Many messages must keep a
394                          stack of queue-ids of queues which they must be returned to. This provides
395                          a light efficient stack for this purpose.
396                      */
397 karl            1.60 class PEGASUS_COMMON_LINKAGE QueueIdStack
398 mike            1.6  {
399                      public:
400                      
401 chip            1.24     QueueIdStack() : _size(0)
402                          {
403 mike            1.6      }
404                      
405 karl            1.59     QueueIdStack(const QueueIdStack& x);
406 mike            1.6  
407 karl            1.59     PEGASUS_EXPLICIT QueueIdStack(Uint32 x);
408 mike            1.6  
409 karl            1.59     PEGASUS_EXPLICIT QueueIdStack(Uint32 x1, Uint32 x2);
410 mike            1.6  
411 chip            1.24     ~QueueIdStack()
412                          {
413 mike            1.6      }
414                      
415 karl            1.59     QueueIdStack& operator=(const QueueIdStack& x);
416 mike            1.6  
417 chip            1.24     Uint32 size() const
418                          {
419 kumpf           1.86         return _size;
420 mike            1.6      }
421                      
422 chip            1.24     Boolean isEmpty() const
423                          {
424 kumpf           1.86         return _size == 0;
425 mike            1.6      }
426                      
427 chip            1.24     void push(Uint32 x)
428 mike            1.6      {
429 karl            1.59 #ifdef PEGASUS_DEBUG
430 kumpf           1.86         if (_size == MAX_SIZE)
431                                  throw StackOverflow();
432 karl            1.59 #endif
433 kumpf           1.86         _items[_size++] = x;
434 mike            1.6      }
435                      
436                          Uint32& top()
437                          {
438 karl            1.59 #ifdef PEGASUS_DEBUG
439 kumpf           1.86         if (_size == 0)
440                                  throw StackUnderflow();
441 karl            1.59 #endif
442 kumpf           1.86         return _items[_size-1];
443 mike            1.6      }
444                      
445 chip            1.24     Uint32 top() const
446 mike            1.6      {
447 kumpf           1.86         return ((QueueIdStack*)this)->top();
448 mike            1.6      }
449                      
450 chip            1.24     void pop()
451 mike            1.6      {
452 karl            1.59 #ifdef PEGASUS_DEBUG
453 kumpf           1.86         if (_size == 0)
454                                  throw StackUnderflow();
455 karl            1.59 #endif
456 kumpf           1.86         _size--;
457 mike            1.6      }
458                      
459                          /** Make a copy of this stack and then pop the top element. */
460 karl            1.59     QueueIdStack copyAndPop() const;
461 mike            1.6  
462                      private:
463                      
464                          // Copy the given stack but then pop the top element:
465 karl            1.59     QueueIdStack(const QueueIdStack& x, int);
466 mike            1.6  
467                          enum { MAX_SIZE = 5 };
468                          Uint32 _items[MAX_SIZE];
469                          Uint32 _size;
470                      };
471 mike            1.4  
472                      PEGASUS_NAMESPACE_END
473                      
474                      #endif /* Pegasus_Message_h */

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2