Correct release notes in RTD index
[ric-plt/xapp-frame-cpp.git] / src / messaging / message.cpp
index 0c6b262..30a0fbc 100644 (file)
@@ -43,7 +43,7 @@
 
 // --------------- private ------------------------------------------------
 
-// --------------- builders -----------------------------------------------
+// --------------- builders/operators  -------------------------------------
 
 /*
        Create a new message wrapper for an existing RMR msg buffer.
@@ -58,6 +58,73 @@ Message::Message( void* mrc, int payload_len ) {
        this->mbuf = rmr_alloc_msg( mrc, payload_len );
 }
 
+/*
+       Copy builder.  Given a source object instance (soi), create a copy.
+       Creating a copy should be avoided as it can be SLOW!
+*/
+Message::Message( const Message& soi ) {
+       int payload_size;
+
+       mrc = soi.mrc;
+       payload_size = rmr_payload_size( soi.mbuf );            // rmr can handle a nil pointer
+       mbuf = rmr_realloc_payload( soi.mbuf, payload_size, RMR_COPY, RMR_CLONE );      
+}
+
+/*
+       Assignment operator. Simiolar to the copycat, but "this" object exists and
+       may have data that needs to be released prior to making a copy of the soi.
+*/
+Message& Message::operator=( const Message& soi ) {
+       int     payload_size;
+
+       if( this != &soi ) {                            // cannot do self assignment
+               if( mbuf != NULL ) {
+                       rmr_free_msg( mbuf );           // release the old one so we don't leak
+               }
+       
+               payload_size = rmr_payload_size( soi.mbuf );            // rmr can handle a nil pointer
+               mrc = soi.mrc;
+               mbuf = rmr_realloc_payload( soi.mbuf, payload_size, RMR_COPY, RMR_CLONE );      
+       }
+
+       return *this;
+}
+
+/*
+       Move builder.  Given a source object instance (soi), move the information from
+       the soi ensuring that the destriction of the soi doesn't trash things from
+       under us.
+*/
+Message::Message( Message&& soi ) {
+       mrc = soi.mrc;
+       mbuf = soi.mbuf;
+
+       soi.mrc = NULL;         // prevent closing of RMR stuff on soi destroy
+       soi.mbuf = NULL;
+}
+
+/*
+       Move Assignment operator. Move the message data to the existing object
+       ensure the object reference is cleaned up, and ensuring that the source
+       object references are removed.
+*/
+Message& Message::operator=( Message&& soi ) {
+       if( this != &soi ) {                            // cannot do self assignment
+               if( mbuf != NULL ) {
+                       rmr_free_msg( mbuf );           // release the old one so we don't leak
+               }
+       
+               mrc = soi.mrc;
+               mbuf = soi.mbuf;
+
+               soi.mrc = NULL;
+               soi.mbuf = NULL;
+       }
+
+       return *this;
+}
+
+
 /*
        Destroyer.
 */
@@ -97,28 +164,30 @@ std::unique_ptr<unsigned char> Message::Copy_payload( ){
 std::unique_ptr<unsigned char> Message::Get_meid(){
        unsigned char* m = NULL;
 
-       if( m != NULL ) {
-               m = (unsigned char *) malloc( sizeof( unsigned char ) * RMR_MAX_MEID );
-               rmr_get_meid( mbuf, m );
-       }
+       m = (unsigned char *) malloc( sizeof( unsigned char ) * RMR_MAX_MEID );
+       rmr_get_meid( mbuf, m );
 
        return std::unique_ptr<unsigned char>( m );
 }
 
+/*
+       Return the total size of the payload (the amount that can be written to
+       as opposed to the portion of the payload which is currently in use.
+       If mbuf isn't valid (nil, or message has a broken header) the return
+       will be -1.
+*/
 int Message::Get_available_size(){
-       if( mbuf != NULL ) {
-               return rmr_payload_size( mbuf );
-       }
-
-       return 0;
+       return rmr_payload_size( mbuf );                // rmr can handle a nil pointer
 }
 
 int    Message::Get_mtype(){
+       int rval = INVALID_MTYPE;
+
        if( mbuf != NULL ) {
-               return mbuf->mtype;
+               rval = mbuf->mtype;
        }
 
-       return INVALID_MTYPE;
+       return rval;
 }
 
 /*
@@ -128,6 +197,8 @@ std::unique_ptr<unsigned char> Message::Get_src(){
        unsigned char* m = NULL;
 
        m = (unsigned char *) malloc( sizeof( unsigned char ) * RMR_MAX_SRC );
+       memset( m, 0, sizeof( unsigned char ) * RMR_MAX_SRC );
+
        if( m != NULL ) {
                rmr_get_src( mbuf, m );
        }
@@ -136,27 +207,37 @@ std::unique_ptr<unsigned char> Message::Get_src(){
 }
 
 int    Message::Get_state( ){
+       int state = INVALID_STATUS;
+
        if( mbuf != NULL ) {
-               return mbuf->state;
+               state =  mbuf->state;
        }
 
-       return INVALID_STATUS;
+       return state;
 }
 
 int    Message::Get_subid(){
+       int     rval = INVALID_SUBID;
+
        if( mbuf != NULL ) {
-               return mbuf->sub_id;
+               rval =mbuf->sub_id;
        }
 
-       return INVALID_SUBID;
+       return rval;
 }
 
+/*
+       Return the amount of the payload (bytes) which is used. See
+       Get_available_size() to get the total usable space in the payload.
+*/
 int    Message::Get_len(){
+       int rval = 0;
+
        if( mbuf != NULL ) {
-               return mbuf->len;
+               rval = mbuf->len;
        }
 
-       return 0;
+       return rval;
 }
 
 /*
@@ -175,7 +256,7 @@ Msg_component Message::Get_payload(){
        return NULL;
 }
 
-void Message::Set_meid( std::unique_ptr<unsigned char> new_meid ) {
+void Message::Set_meid( std::shared_ptr<unsigned char> new_meid ) {
        if( mbuf != NULL ) {
                rmr_str2meid( mbuf, (unsigned char *) new_meid.get() );
        }
@@ -187,6 +268,12 @@ void Message::Set_mtype( int new_type ){
        }
 }
 
+void Message::Set_len( int new_len ){
+       if( mbuf != NULL  && new_len >= 0 ) {
+               mbuf->len = new_len;
+       }
+}
+
 void Message::Set_subid( int new_subid ){
        if( mbuf != NULL ) {
                mbuf->sub_id = new_subid;
@@ -202,12 +289,14 @@ void Message::Set_subid( int new_subid ){
        Exposed to the user, but not expected to be frequently used.
 */
 bool Message::Send( ) {
-       if( mbuf == NULL ) {
-               return false;
+       bool state = false;
+
+       if( mbuf != NULL ) {
+               mbuf =  rmr_send_msg( mrc, mbuf );      // send and pick up new mbuf
+               state = mbuf->state == RMR_OK;          // overall state for caller
        }
 
-       mbuf =  rmr_send_msg( mrc, mbuf );
-       return mbuf->state == RMR_OK;
+       return state;
 }
 
 /*
@@ -215,12 +304,14 @@ bool Message::Send( ) {
        Exposed to the user, but not expected to be frequently used.
 */
 bool Message::Reply( ) {
-       if( mbuf == NULL ) {
-               return false;
+       bool state = false;
+
+       if( mbuf != NULL ) {
+               mbuf =  rmr_rts_msg( mrc, mbuf );               // send and pick up new mbuf
+               state = mbuf->state == RMR_OK;                  // state for caller based on send
        }
 
-       mbuf =  rmr_rts_msg( mrc, mbuf );
-       return mbuf->state == RMR_OK;
+       return state;
 }
 
 /*
@@ -235,31 +326,39 @@ bool Message::Reply( ) {
        This is public, but most users should use Send_msg or Send_response functions.
 */
 bool Message::Send( int mtype, int subid, int payload_len, unsigned char* payload, int stype ) {
+       bool state = false;
 
-       if( mbuf == NULL ) {
-               return false;
-       }
+       if( mbuf != NULL ) {
+               if( mtype != NO_CHANGE ) {
+                       mbuf->mtype = mtype;
+               }
+               if( subid != NO_CHANGE ) {
+                       mbuf->sub_id = subid;
+               }
 
-       mbuf->mtype = mtype;
-       mbuf->sub_id = subid;
-       mbuf->len = payload_len;
+               if( payload_len != NO_CHANGE ) {
+                       mbuf->len = payload_len;
+               }
 
-       if( payload != NULL ) {                 // if we have a payload, ensure msg has room, realloc if needed, then copy
-               mbuf = rmr_realloc_payload( mbuf, payload_len, RMR_NO_COPY, RMR_NO_CLONE );             // ensure message is large enough
-               if( mbuf == NULL ) {
-                       return false;
+               if( payload != NULL ) {                 // if we have a payload, ensure msg has room, realloc if needed, then copy
+                       mbuf = rmr_realloc_payload( mbuf, payload_len, RMR_NO_COPY, RMR_NO_CLONE );             // ensure message is large enough
+                       if( mbuf == NULL ) {
+                               return false;
+                       }
+
+                       memcpy( mbuf->payload, payload, mbuf->len );
                }
 
-               memcpy( mbuf->payload, payload, mbuf->len );
-       }
+               if( stype == RESPONSE ) {
+                       mbuf = rmr_rts_msg( mrc, mbuf );
+               } else {
+                       mbuf = rmr_send_msg( mrc, mbuf );
+               }
 
-       if( stype == RESPONSE ) {
-               mbuf = rmr_rts_msg( mrc, mbuf );
-       } else {
-               mbuf = rmr_send_msg( mrc, mbuf );
+               state = mbuf->state == RMR_OK;
        }
 
-       return mbuf->state == RMR_OK;
+       return state;
 }
 
 /*
@@ -271,7 +370,7 @@ bool Message::Send( int mtype, int subid, int payload_len, unsigned char* payloa
        The second form of the call allows for a stack allocated buffer (e.g. char foo[120]) to
        be passed as the payload.
 */
-bool Message::Send_response(  int mtype, int subid, int response_len, std::unique_ptr<unsigned char> response ) {
+bool Message::Send_response(  int mtype, int subid, int response_len, std::shared_ptr<unsigned char> response ) {
        return Send( mtype, subid, response_len, response.get(), RESPONSE );
 }
 
@@ -282,12 +381,12 @@ bool Message::Send_response(  int mtype, int subid, int response_len, unsigned c
 /*
        These allow a response message to be sent without changing the mtype/subid.
 */
-bool Message::Send_response(  int response_len, std::unique_ptr<unsigned char> response ) {
-       return Send( NOCHANGE, NOCHANGE, response_len, response.get(), RESPONSE );
+bool Message::Send_response(  int response_len, std::shared_ptr<unsigned char> response ) {
+       return Send( NO_CHANGE, NO_CHANGE, response_len, response.get(), RESPONSE );
 }
 
 bool Message::Send_response(  int response_len, unsigned char* response ) {
-       return Send( NOCHANGE, NOCHANGE, response_len, response, RESPONSE );
+       return Send( NO_CHANGE, NO_CHANGE, response_len, response, RESPONSE );
 }
 
 
@@ -300,7 +399,7 @@ bool Message::Send_response(  int response_len, unsigned char* response ) {
        Return is a new mbuf suitable for sending another message, or the original buffer with
        a bad state sent if there was a failure.
 */
-bool Message::Send_msg(  int mtype, int subid, int payload_len, std::unique_ptr<unsigned char> payload ) {
+bool Message::Send_msg(  int mtype, int subid, int payload_len, std::shared_ptr<unsigned char> payload ) {
        return Send( mtype, subid, payload_len, payload.get(), MESSAGE );
 }
 
@@ -311,10 +410,10 @@ bool Message::Send_msg(  int mtype, int subid, int payload_len, unsigned char* p
 /*
        Similar send functions that allow the message type/subid to remain unchanged
 */
-bool Message::Send_msg(  int payload_len, std::unique_ptr<unsigned char> payload ) {
-       return Send( NOCHANGE, NOCHANGE, payload_len, payload.get(), MESSAGE );
+bool Message::Send_msg(  int payload_len, std::shared_ptr<unsigned char> payload ) {
+       return Send( NO_CHANGE, NO_CHANGE, payload_len, payload.get(), MESSAGE );
 }
 
 bool Message::Send_msg(  int payload_len, unsigned char* payload ) {
-       return Send( NOCHANGE, NOCHANGE, payload_len, payload, MESSAGE );
+       return Send( NO_CHANGE, NO_CHANGE, payload_len, payload, MESSAGE );
 }