python/loudmouth.pyx
changeset 194 89d481905356
parent 193 bafe7fc8caf4
child 195 c6ae0ebc7733
equal deleted inserted replaced
193:bafe7fc8caf4 194:89d481905356
     1 # -*- Mode: Python -*-
       
     2 
       
     3 cdef extern from "Python.h":
       
     4     ctypedef struct PyObject
       
     5     void Py_INCREF (object)
       
     6     void Py_DECREF (object)
       
     7     void Py_XINCREF (object)
       
     8     void Py_XDECREF (object)
       
     9     
       
    10 cdef extern from "glib/gerror.h":
       
    11     ctypedef struct GError:
       
    12         int quark
       
    13         int domain
       
    14         char* message
       
    15     
       
    16 cdef extern from "stdlib.h":
       
    17     cdef void *malloc(int size)
       
    18     cdef void free(void *ptr)
       
    19 
       
    20 cdef extern from "glib/gtypes.h":
       
    21     ctypedef struct GDestroyNotify
       
    22     ctypedef struct gboolean
       
    23     
       
    24 cdef extern from "loudmouth/loudmouth.h":
       
    25     ctypedef enum LmMessageType:
       
    26         LM_MESSAGE_TYPE_MESSAGE
       
    27         LM_MESSAGE_TYPE_PRESENCE
       
    28         LM_MESSAGE_TYPE_IQ
       
    29         LM_MESSAGE_TYPE_STREAM
       
    30         LM_MESSAGE_TYPE_STREAM_ERROR
       
    31         LM_MESSAGE_TYPE_UNKNOWN
       
    32 
       
    33     ctypedef enum LmMessageSubType:
       
    34         LM_MESSAGE_SUB_TYPE_NOT_SET
       
    35         LM_MESSAGE_SUB_TYPE_AVAILABLE
       
    36         LM_MESSAGE_SUB_TYPE_NORMAL
       
    37         LM_MESSAGE_SUB_TYPE_CHAT
       
    38         LM_MESSAGE_SUB_TYPE_GROUPCHAT
       
    39         LM_MESSAGE_SUB_TYPE_HEADLINE
       
    40         LM_MESSAGE_SUB_TYPE_UNAVAILABLE
       
    41         LM_MESSAGE_SUB_TYPE_PROBE
       
    42         LM_MESSAGE_SUB_TYPE_SUBSCRIBE
       
    43         LM_MESSAGE_SUB_TYPE_UNSUBSCRIBE
       
    44         LM_MESSAGE_SUB_TYPE_SUBSCRIBED
       
    45         LM_MESSAGE_SUB_TYPE_UNSUBSCRIBED
       
    46         LM_MESSAGE_SUB_TYPE_GET
       
    47         LM_MESSAGE_SUB_TYPE_SET
       
    48         LM_MESSAGE_SUB_TYPE_RESULT
       
    49         LM_MESSAGE_SUB_TYPE_ERROR
       
    50 
       
    51     ctypedef enum LmHandlerResult:
       
    52         LM_HANDLER_RESULT_REMOVE_MESSAGE
       
    53         LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS
       
    54 
       
    55     ctypedef enum LmHandlerPriority:
       
    56         LM_HANDLER_PRIORITY_LAST
       
    57         LM_HANDLER_PRIORITY_NORMAL
       
    58         LM_HANDLER_PRIORITY_FIRST
       
    59 
       
    60     ctypedef enum LmDisconnectReason:
       
    61         LM_DISCONNECT_REASON_OK
       
    62         LM_DISCONNECT_REASON_PING_TIME_OUT
       
    63         LM_DISCONNECT_REASON_HUP
       
    64         LM_DISCONNECT_REASON_ERROR
       
    65         LM_DISCONNECT_REASON_UNKNOWN
       
    66 
       
    67     ctypedef enum _LmError:
       
    68         LM_ERROR_CONNECTION_NOT_OPEN
       
    69         LM_ERROR_CONNECTION_OPEN
       
    70         LM_ERROR_AUTH_FAILED
       
    71 
       
    72     ctypedef struct LmConnection
       
    73     ctypedef struct LmMessage
       
    74     ctypedef struct LmMessageNode
       
    75     ctypedef struct LmMessageHandler
       
    76     ctypedef struct LmMessagePriv
       
    77     
       
    78     ctypedef struct GError
       
    79     ctypedef struct GDestroyNotify
       
    80     
       
    81     ctypedef void (* LmResultFunction) (LmConnection *connection, int success, void* user_data)
       
    82     ctypedef void (* LmDisconnectFunction) (LmConnection *connection, LmDisconnectReason reason, void* user_data)
       
    83     
       
    84     ctypedef LmHandlerResult (* LmHandleMessageFunction) (LmMessageHandler *handler, LmConnection *connection, LmMessage *message, void* user_data)
       
    85     
       
    86     LmConnection*        lm_connection_new (char* server)
       
    87     int                  lm_connection_open (LmConnection* connection, LmResultFunction function, void* user_data, GDestroyNotify notify, GError** error)
       
    88     int                  lm_connection_open_and_block (LmConnection* connection, GError** error)
       
    89     int                  lm_connection_close (LmConnection* connection, GError** error)
       
    90     int                  lm_connection_authenticate (LmConnection* connection, char* username, char* password, char* resource, LmResultFunction function, void* user_data, GDestroyNotify notify, GError** error)
       
    91     int                  lm_connection_authenticate_and_block (LmConnection* connection, char* username, char* password, char* resource, GError** error)
       
    92     gboolean             lm_connection_is_open (LmConnection* connection)
       
    93     gboolean             lm_connection_is_authenticated (LmConnection* connection)
       
    94     char*                lm_connection_get_server (LmConnection* connection)
       
    95     void                 lm_connection_set_server (LmConnection* connection, char* server)
       
    96     int                  lm_connection_get_port (LmConnection* connection)
       
    97     void                 lm_connection_set_port (LmConnection* connection, int port)
       
    98     gboolean             lm_connection_get_use_ssl (LmConnection* connection)
       
    99     void                 lm_connection_set_use_ssl (LmConnection* connection, int use_ssl)
       
   100     int                  lm_connection_send (LmConnection* connection, LmMessage* message, GError** error)
       
   101     int                  lm_connection_send_with_reply (LmConnection* connection, LmMessage* message, LmMessageHandler* handler, GError** error)
       
   102     LmMessage*           lm_connection_send_with_reply_and_block (LmConnection* connection, LmMessage* message, GError** error)
       
   103     void                 lm_connection_register_message_handler (LmConnection* connection, LmMessageHandler* handler, LmMessageType type, LmHandlerPriority priority)
       
   104     void                 lm_connection_unregister_message_handler (LmConnection* connection, LmMessageHandler* handler, LmMessageType type)
       
   105     void                 lm_connection_set_disconnect_function (LmConnection* connection, LmDisconnectFunction function, void* user_data, GDestroyNotify notify)
       
   106     int                  lm_connection_send_raw (LmConnection* connection, char* str, GError** error)
       
   107     LmConnection*        lm_connection_ref (LmConnection* connection)
       
   108     void                 lm_connection_unref (LmConnection* connection)
       
   109 
       
   110     LmMessage*           lm_message_new (char* to, LmMessageType type)
       
   111     LmMessage*           lm_message_new_with_sub_type (char* to, LmMessageType type, LmMessageSubType sub_type)
       
   112     LmMessageType        lm_message_get_type (LmMessage* message)
       
   113     LmMessageSubType     lm_message_get_sub_type (LmMessage* message)
       
   114     LmMessageNode*       lm_message_get_node (LmMessage* message)
       
   115     LmMessage*           lm_message_ref (LmMessage* message)
       
   116     void                 lm_message_unref (LmMessage* message)
       
   117 
       
   118     LmMessageHandler*    lm_message_handler_new (LmHandleMessageFunction function, void* user_data, GDestroyNotify notify)
       
   119     void                 lm_message_handler_invalidate (LmMessageHandler* handler)
       
   120     int                  lm_message_handler_is_valid (LmMessageHandler* handler)
       
   121     LmMessageHandler*    lm_message_handler_ref (LmMessageHandler* handler)
       
   122     void                 lm_message_handler_unref (LmMessageHandler* handler)
       
   123 
       
   124     char*                lm_message_node_get_value (LmMessageNode* node)
       
   125     void                 lm_message_node_set_value (LmMessageNode* node, char* value)
       
   126     LmMessageNode*       lm_message_node_add_child (LmMessageNode* node, char* name, char* value)
       
   127     void                 lm_message_node_set_attribute (LmMessageNode* node, char* name, char* value)
       
   128     char*                lm_message_node_get_attribute (LmMessageNode* node, char* name)
       
   129     LmMessageNode*       lm_message_node_get_child (LmMessageNode* message_node, char* child_name)
       
   130     LmMessageNode*       lm_message_node_find_child (LmMessageNode* message_node, char* child_name)
       
   131     int                  lm_message_node_get_raw_mode (LmMessageNode* node)
       
   132     void                 lm_message_node_set_raw_mode (LmMessageNode* node, int raw_mode)
       
   133     LmMessageNode*       lm_message_node_ref (LmMessageNode* node)
       
   134     void                 lm_message_node_unref (LmMessageNode* node)
       
   135     char*                lm_message_node_to_string (LmMessageNode* node)
       
   136 
       
   137 class LmError(Exception):
       
   138     pass
       
   139 
       
   140 # Export all enum values
       
   141 MESSAGE_TYPE_MESSAGE      = LM_MESSAGE_TYPE_MESSAGE
       
   142 MESSAGE_TYPE_PRESENCE     = LM_MESSAGE_TYPE_PRESENCE
       
   143 MESSAGE_TYPE_IQ           = LM_MESSAGE_TYPE_IQ
       
   144 MESSAGE_TYPE_STREAM       = LM_MESSAGE_TYPE_STREAM
       
   145 MESSAGE_TYPE_STREAM_ERROR = LM_MESSAGE_TYPE_STREAM_ERROR
       
   146 MESSAGE_TYPE_UNKNOWN      = LM_MESSAGE_TYPE_UNKNOWN
       
   147 
       
   148 MESSAGE_SUB_TYPE_NOT_SET      = LM_MESSAGE_SUB_TYPE_NOT_SET
       
   149 MESSAGE_SUB_TYPE_AVAILABLE    = LM_MESSAGE_SUB_TYPE_AVAILABLE
       
   150 MESSAGE_SUB_TYPE_NORMAL       = LM_MESSAGE_SUB_TYPE_NORMAL
       
   151 MESSAGE_SUB_TYPE_CHAT         = LM_MESSAGE_SUB_TYPE_CHAT
       
   152 MESSAGE_SUB_TYPE_GROUPCHAT    = LM_MESSAGE_SUB_TYPE_GROUPCHAT
       
   153 MESSAGE_SUB_TYPE_HEADLINE     = LM_MESSAGE_SUB_TYPE_HEADLINE
       
   154 MESSAGE_SUB_TYPE_UNAVAILABLE  = LM_MESSAGE_SUB_TYPE_UNAVAILABLE
       
   155 MESSAGE_SUB_TYPE_PROBE        = LM_MESSAGE_SUB_TYPE_PROBE
       
   156 MESSAGE_SUB_TYPE_SUBSCRIBE    = LM_MESSAGE_SUB_TYPE_SUBSCRIBE
       
   157 MESSAGE_SUB_TYPE_UNSUBSCRIBE  = LM_MESSAGE_SUB_TYPE_UNSUBSCRIBE
       
   158 MESSAGE_SUB_TYPE_SUBSCRIBED   = LM_MESSAGE_SUB_TYPE_SUBSCRIBED
       
   159 MESSAGE_SUB_TYPE_UNSUBSCRIBED = LM_MESSAGE_SUB_TYPE_UNSUBSCRIBED
       
   160 MESSAGE_SUB_TYPE_GET          = LM_MESSAGE_SUB_TYPE_GET
       
   161 MESSAGE_SUB_TYPE_SET          = LM_MESSAGE_SUB_TYPE_SET
       
   162 MESSAGE_SUB_TYPE_RESULT       = LM_MESSAGE_SUB_TYPE_RESULT
       
   163 MESSAGE_SUB_TYPE_ERROR        = LM_MESSAGE_SUB_TYPE_ERROR
       
   164 
       
   165 HANDLER_RESULT_REMOVE_MESSAGE      = LM_HANDLER_RESULT_REMOVE_MESSAGE
       
   166 HANDLER_RESULT_ALLOW_MORE_HANDLERS = LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS
       
   167 
       
   168 HANDLER_PRIORITY_LAST   = LM_HANDLER_PRIORITY_LAST
       
   169 HANDLER_PRIORITY_NORMAL = LM_HANDLER_PRIORITY_NORMAL
       
   170 HANDLER_PRIORITY_FIRST  = LM_HANDLER_PRIORITY_FIRST
       
   171 
       
   172 DISCONNECT_REASON_OK            = LM_DISCONNECT_REASON_OK
       
   173 DISCONNECT_REASON_PING_TIME_OUT = LM_DISCONNECT_REASON_PING_TIME_OUT
       
   174 DISCONNECT_REASON_HUP           = LM_DISCONNECT_REASON_HUP
       
   175 DISCONNECT_REASON_ERROR         = LM_DISCONNECT_REASON_ERROR
       
   176 DISCONNECT_REASON_UNKNOWN       = LM_DISCONNECT_REASON_UNKNOWN
       
   177 
       
   178 # XXX: Replace with exceptions
       
   179 ERROR_CONNECTION_NOT_OPEN = LM_ERROR_CONNECTION_NOT_OPEN
       
   180 ERROR_CONNECTION_OPEN     = LM_ERROR_CONNECTION_OPEN
       
   181 ERROR_AUTH_FAILED         = LM_ERROR_AUTH_FAILED
       
   182 
       
   183 cdef struct DataHelper:
       
   184     PyObject *function
       
   185     PyObject *extra
       
   186     
       
   187 cdef void cresult_function_handler (LmConnection *connection, int success, void *user_data):
       
   188     cdef DataHelper *data
       
   189     data = <DataHelper*>user_data
       
   190     
       
   191     conn = Connection(_create=0)
       
   192     conn._set_conn(<object>connection)
       
   193 
       
   194     function = <object>data.function
       
   195     if data.extra:
       
   196         extra = <object>data.extra
       
   197         function(conn, success, extra)
       
   198     else:
       
   199         function(conn, success)    
       
   200     
       
   201 cdef class _Connection:
       
   202     cdef LmConnection *conn
       
   203     
       
   204     def __init__(self, server=None, _create=1):
       
   205 
       
   206         if not _create:
       
   207             return 1
       
   208         
       
   209         self.conn = lm_connection_new(server)
       
   210         lm_connection_ref(self.conn)
       
   211 
       
   212     def _set_conn(self, conn):
       
   213         self.conn = <LmConnection*>conn
       
   214         
       
   215     def _get_conn(self):
       
   216         return <object>self.conn
       
   217     
       
   218     def open(self, function, extra=None):
       
   219         cdef GError *error
       
   220         cdef DataHelper *data
       
   221         error = NULL
       
   222 
       
   223         data = <DataHelper*>malloc(sizeof(DataHelper))
       
   224         data.function = <PyObject*>function
       
   225         Py_XINCREF(function)
       
   226         if extra:
       
   227             data.extra = <PyObject*>extra
       
   228             Py_XINCREF(extra)
       
   229         else:
       
   230             data.extra = NULL
       
   231 
       
   232         retval = lm_connection_open (self.conn,
       
   233                                      cresult_function_handler,
       
   234                                      <void*>data,  #<void*>function,
       
   235                                      <GDestroyNotify>NULL,
       
   236                                      &error)
       
   237         if not retval:
       
   238             raise LmError, error.message
       
   239     
       
   240     def open_and_block(self):
       
   241         cdef GError *error
       
   242         error = NULL
       
   243         
       
   244         if not lm_connection_open_and_block(self.conn, &error):
       
   245             raise LmError, error.message
       
   246 
       
   247     def close(self):
       
   248         cdef GError *error
       
   249         error = NULL
       
   250         
       
   251         if not lm_connection_close(self.conn, &error):
       
   252             raise LmError, error.message
       
   253         
       
   254     def authenticate(self, username, password, resource, function, extra=None):
       
   255         cdef GError *error
       
   256         cdef DataHelper *data
       
   257         error = NULL
       
   258 
       
   259         data = <DataHelper*>malloc(sizeof(DataHelper))
       
   260         data.function = <PyObject*>function
       
   261         Py_XINCREF(function)
       
   262         if extra:
       
   263             data.extra = <PyObject*>extra
       
   264             Py_XINCREF(extra)
       
   265         else:
       
   266             data.extra = NULL
       
   267 
       
   268         retval = lm_connection_authenticate (self.conn, username, password, resource,
       
   269                                              cresult_function_handler,
       
   270                                              <void*>data,
       
   271                                              <GDestroyNotify>NULL,
       
   272                                              &error)
       
   273         if not retval:
       
   274             raise LmError, error.message
       
   275         
       
   276     def authenticate_and_block(self, username, password, resource):
       
   277         cdef GError *error
       
   278         error = NULL
       
   279         
       
   280         retval = lm_connection_authenticate_and_block(self.conn, username, password, resource, &error)
       
   281         if not retval:
       
   282             raise LmError, error.message
       
   283 
       
   284     def is_open(self):
       
   285         return <int>lm_connection_is_open(self.conn)
       
   286 
       
   287     def is_authenticated(self):
       
   288         return <int>lm_connection_is_authenticated(self.conn)
       
   289 
       
   290     def get_server(self):
       
   291         return lm_connection_get_server(self.conn)
       
   292 
       
   293     def set_server(self, server):
       
   294         lm_connection_set_server(self.conn, server)
       
   295 
       
   296     def get_port(self):
       
   297         return lm_connection_get_port(self.conn)
       
   298 
       
   299     def set_port(self, port):
       
   300         lm_connection_set_port(self.conn, port)  
       
   301 
       
   302     def get_use_ssl(self):
       
   303         return <int>lm_connection_get_use_ssl(self.conn)
       
   304 
       
   305     def set_use_ssl(self, boolean):
       
   306         lm_connection_set_use_ssl(self.conn, boolean)
       
   307 
       
   308     def send(self, message):
       
   309         cdef GError *error
       
   310         error = NULL
       
   311 
       
   312         msg = message._get_msg(message)
       
   313         retval = lm_connection_send(self.conn, <LmMessage*>msg, &error)
       
   314         if not retval:
       
   315             raise LmError, error.message
       
   316     
       
   317     #int    lm_connection_send_with_reply (LmConnection* connection, LmMessage* message, LmMessageHandler* handler, GError** error)
       
   318     #void   lm_connection_register_message_handler (LmConnection* connection, LmMessageHandler* handler, LmMessageType type, LmHandlerPriority priority)
       
   319     #void   lm_connection_unregister_message_handler (LmConnection* connection, LmMessageHandler* handler, LmMessageType type)
       
   320     #void   lm_connection_set_disconnect_function (LmConnection* connection, LmDisconnectFunction function, void* user_data, GDestroyNotify notify)
       
   321 
       
   322     def send_with_reply(self, message, handler, error):
       
   323         pass
       
   324     
       
   325     def send_with_reply_and_block(self, message):
       
   326         cdef GError *error
       
   327         error = NULL
       
   328 
       
   329         print 'send_with_reply_and_block', message
       
   330         
       
   331         msg = message._get_msg()
       
   332         print msg
       
   333         retval = <object>lm_connection_send_with_reply_and_block(self.conn,
       
   334                                                                  <LmMessage*>msg,
       
   335                                                                  &error)
       
   336         print 'returned'
       
   337         print retval
       
   338         if not retval:
       
   339             raise LmError, error.message
       
   340         
       
   341         msg2 = Message(_create=0)
       
   342         msg2.set_msg(<object>retval)
       
   343         return msg2
       
   344 
       
   345     def send_raw(self, str):
       
   346         cdef GError *error
       
   347         error = NULL
       
   348 
       
   349         if not lm_connection_send_raw(self.conn, raw, &error):
       
   350             raise LmError, error.message
       
   351     
       
   352     def register_message_handler(self, handler, type, priority):
       
   353         pass
       
   354 
       
   355     def unregister_message_handler(self, handler, type, notify):
       
   356         pass
       
   357 
       
   358 cdef class _Message:
       
   359     cdef LmMessage *msg
       
   360     def __init__ (self, to, type, sub_type=None, _create=1):
       
   361 
       
   362         if not _create:
       
   363             return 1
       
   364 
       
   365         if not sub_type:
       
   366             self.msg = lm_message_new(to, type)
       
   367         else:
       
   368             self.msg = lm_message_new_with_sub_type(to, type, subtype)
       
   369 
       
   370         lm_message_ref(self.msg)
       
   371 
       
   372     def _set_msg(self, msg):
       
   373         self.msg = <LmMessage*>msg
       
   374 
       
   375     def _get_msg(self):
       
   376         return <object>self.msg
       
   377 
       
   378     def get_type(self):
       
   379         return lm_message_get_type(self.msg)
       
   380     
       
   381     def get_sub_type(self):
       
   382         return lm_message_get_sub_type(self.msg)
       
   383 
       
   384     def get_node(self):
       
   385         retval = <object>lm_message_get_node(self.msg)
       
   386         node = MessageNode(_create=0)
       
   387         node._set_node(<object>retval)
       
   388         return node
       
   389     
       
   390 cdef LmHandlerResult cmessage_function_handler (LmMessageHandler *handler,
       
   391                                                 LmConnection     *connection,
       
   392                                                 LmMessage        *message,
       
   393                                                 void             *user_data):
       
   394     function = <object>user_data
       
   395     
       
   396     hand = MessageHandler(_create=0)
       
   397     hand._set_handler(<object>handler)
       
   398 
       
   399     conn = Connection(_create=0)
       
   400     conn._set_conn(<object>connection)
       
   401     
       
   402     msg = Message(_create=0)
       
   403     msg._set_msg(<object>message)
       
   404 
       
   405     retval = function(hand, conn, msg)
       
   406 
       
   407     return retval
       
   408 
       
   409 cdef class MessageHandler:
       
   410     cdef LmMessageHandler* handler
       
   411     def __init__(self, function, _create=0):
       
   412         if not _create:
       
   413             return 0
       
   414 
       
   415         self.handler = <LmMessageHandler*>lm_message_handler_new(
       
   416             cmessage_function_handler,
       
   417             <void*>function,
       
   418             <GDestroyNotify>NULL)
       
   419 
       
   420         lm_message_handler_ref(self.handler)
       
   421         
       
   422     def _set_handler(self, handler):
       
   423         self.handler = <LmMessageHandler*>handler
       
   424 
       
   425     def _get_handler(self, handler):
       
   426         return <object>self.handler
       
   427 
       
   428     def invalidate(self):
       
   429         lm_message_handler_invalidate(self.handler)
       
   430         
       
   431     def is_valid(self):
       
   432         return lm_message_handler_is_valid(self.handler)
       
   433 
       
   434 cdef class MessageNode:
       
   435     cdef LmMessageNode *node
       
   436     def __init__(self, _create=1):
       
   437         if _create:
       
   438             raise TypeError, "MessageNode is an abstract class"
       
   439 
       
   440     def _set_node(self, node):
       
   441         self.node = <LmMessageNode*>node
       
   442         
       
   443     def _get_node(self, node):
       
   444         return <object>self.node
       
   445 
       
   446     def get_value(self):
       
   447         return lm_message_node_get_value(self.node)
       
   448 
       
   449     def set_value(self, value):
       
   450         lm_message_node_set_value(self.node, value)
       
   451 
       
   452     def add_child(self, name, value):
       
   453         retval = <object>lm_message_node_add_child(self.node, name, value)
       
   454         node = MessageNode(_create=0)
       
   455         node._set_node(<object>retval)
       
   456         return node
       
   457             
       
   458     def set_attribute(self, name, value):
       
   459         lm_message_node_set_attribute(self.node, name, value)
       
   460 
       
   461     def get_attribute(self, name):
       
   462         return lm_message_node_get_attribute(self.node, name)
       
   463 
       
   464     def get_child(self, child_name):
       
   465         retval = <object>lm_message_node_get_child(self.node, name)
       
   466         node = MessageNode(_create=0)
       
   467         node._set_node(<object>retval)
       
   468         return node
       
   469     
       
   470     def find_child(self, child_name):
       
   471         retval = <object>lm_message_node_find_child(self.node, name)
       
   472         node = MessageNode(_create=0)
       
   473         node._set_node(<object>retval)
       
   474         return node
       
   475     
       
   476     def get_raw_mode(self):
       
   477         return lm_message_node_get_raw_mode(self.node)
       
   478     
       
   479     def set_raw_mode(self, raw_mode):
       
   480         lm_message_node_set_raw_mode(self.node, raw_mode)
       
   481 
       
   482     def to_string(self):
       
   483         return lm_message_node_to_string(self.node)
       
   484