[Spread-cvs] commit: r315 - in trunk: daemon examples include libspread

jonathan at spread.org jonathan at spread.org
Wed Mar 1 08:12:14 EST 2006


Author: jonathan
Date: 2006-03-01 08:12:14 -0500 (Wed, 01 Mar 2006)
New Revision: 315

Modified:
   trunk/daemon/Changelog
   trunk/examples/simple_user.c
   trunk/examples/user.c
   trunk/include/sp.h
   trunk/include/sp_func.h
   trunk/libspread/fl.c
   trunk/libspread/sp.c
Log:
Include nice membership body parsing functions for applications to use. These
replace the old method of walking through the byte array in the membership body
to extract the vs_sets and gid. Deprecate the old functions SP_get_offset*
as they are extremely confusing to use. New functions SP_get_memb_info(), 
SP_get_vs_sets_info() and SP_get_vs_set_members() return strutures with the 
fields filled in.

Update flush library to use new api and update example programs.


Modified: trunk/daemon/Changelog
===================================================================
--- trunk/daemon/Changelog	2006-02-21 05:26:22 UTC (rev 314)
+++ trunk/daemon/Changelog	2006-03-01 13:12:14 UTC (rev 315)
@@ -1,3 +1,14 @@
+Wed Mar  1 08:05:32 2006  Jonathan Stanton  <jonathan at cnds.jhu.edu>
+
+	* libspread/sp.c, fl.c, include/sp.h, sp_func.h (SP_get_vs* memb_info()):
+	Add new membership parsing functions SP_get_memb_info(),
+	SP_get_vs_sets_info() and SP_get_vs_set_members() to analyze
+	the contents of the mesage body of membership messages. 
+	Deprecate old functions that just gave byte locations within 
+	body as they are too confusing. 
+	* examples/user.c, simple_user.c: Update example programs
+	to use new membership parsing functions.
+
 Wed Feb  8 03:44:23 2006  Jonathan Stanton  <jonathan at cnds.jhu.edu>
 
 	* arch.h: Add HAVE_STRERROR for Windows builds. This avoids

Modified: trunk/examples/simple_user.c
===================================================================
--- trunk/examples/simple_user.c	2006-02-21 05:26:22 UTC (rev 314)
+++ trunk/examples/simple_user.c	2006-03-01 13:12:14 UTC (rev 315)
@@ -102,9 +102,8 @@
 static	char		mess[102400];
 	char		sender[MAX_GROUP_NAME];
 	char		target_groups[100][MAX_GROUP_NAME];
-	group_id	*grp_id;
 	int		num_groups;
-	int		num_bytes;
+        membership_info memb_info;
 	int		service_type;
 	int16		mess_type;
 	int		endian_mismatch;
@@ -136,11 +135,14 @@
 
 	}else if( Is_membership_mess( service_type ) ){
 		/* A membership notification */
+                ret = SP_get_memb_info( mess, service_type, &memb_info );
+                if (ret < 0) {
+                        printf("BUG: membership message does not have valid body\n");
+                        SP_error( ret );
+                        exit( 1 );
+                }
 		if     ( Is_reg_memb_mess( service_type ) )
 		{
-			num_bytes = 0;
-			grp_id = (group_id *)&mess[num_bytes];
-			num_bytes += sizeof( group_id );
 			printf("received REGULAR membership ");
 			if( Is_caused_join_mess( service_type ) ) printf("caused by JOIN ");
 			if( Is_caused_leave_mess( service_type ) ) printf("caused by LEAVE ");
@@ -149,7 +151,7 @@
 				sender, num_groups );
 			for( i=0; i < num_groups; i++ )
 				printf("\t%s\n", &target_groups[i][0] );
-			printf("grp id is %d %d %d\n",grp_id->id[0], grp_id->id[1], grp_id->id[2] );
+			printf("grp id is %d %d %d\n",memb_info.gid.id[0], memb_info.gid.id[1], memb_info.gid.id[2] );
 		}else if( Is_transition_mess(   service_type ) ) {
 			printf("received TRANSITIONAL membership for group %s\n", sender );
 		}else if( Is_caused_leave_mess( service_type ) ){

Modified: trunk/examples/user.c
===================================================================
--- trunk/examples/user.c	2006-02-21 05:26:22 UTC (rev 314)
+++ trunk/examples/user.c	2006-03-01 13:12:14 UTC (rev 315)
@@ -80,6 +80,8 @@
 static  int     To_exit = 0;
 
 #define MAX_MESSLEN     102400
+#define MAX_VSSETS      10
+#define MAX_MEMBERS     100
 
 #ifdef	_REENTRANT
 
@@ -383,15 +385,13 @@
 
 static	char		 mess[MAX_MESSLEN];
 	char		 sender[MAX_GROUP_NAME];
-	char		 target_groups[100][MAX_GROUP_NAME];
-	group_id	*grp_id_ptr;
-        int32u          *num_vs_sets_ptr;
-        int32u           local_vs_set_offset;
-	char  		*vs_set_size_ptr;
-        int32u           vs_set_size;
-	char		*vs_set_members;
+	char		 target_groups[MAX_MEMBERS][MAX_GROUP_NAME];
+        membership_info  memb_info;
+        vs_set_info      vssets[MAX_VSSETS];
+        unsigned int     my_vsset_index;
+        int              num_vs_sets;
+        char             members[MAX_MEMBERS][MAX_GROUP_NAME];
 	int		 num_groups;
-	int		 num_bytes;
 	int		 service_type;
 	int16		 mess_type;
 	int		 endian_mismatch;
@@ -408,7 +408,7 @@
                 if ( (ret == GROUPS_TOO_SHORT) || (ret == BUFFER_TOO_SHORT) ) {
                         service_type = DROP_RECV;
                         printf("\n========Buffers or Groups too Short=======\n");
-                        ret = SP_receive( Mbox, &service_type, sender, 100, &num_groups, target_groups, 
+                        ret = SP_receive( Mbox, &service_type, sender, MAX_MEMBERS, &num_groups, target_groups, 
                                           &mess_type, &endian_mismatch, sizeof(mess), mess );
                 }
         }
@@ -435,47 +435,48 @@
 			sender, mess_type, endian_mismatch, num_groups, ret, mess );
 	}else if( Is_membership_mess( service_type ) )
         {
+                ret = SP_get_memb_info( mess, service_type, &memb_info );
+                if (ret < 0) {
+                        printf("BUG: membership message does not have valid body\n");
+                        SP_error( ret );
+                        exit( 1 );
+                }
 		if     ( Is_reg_memb_mess( service_type ) )
 		{
-			num_bytes           = SP_get_gid_offset_memb_mess();
-			grp_id_ptr          = (group_id *)&mess[num_bytes];
-			num_bytes           = SP_get_num_vs_sets_offset_memb_mess();
-			num_vs_sets_ptr     = (int32u *)&mess[num_bytes];
-                        local_vs_set_offset = SP_get_local_vs_set_offset_memb_mess(mess);
-			num_bytes           = SP_get_first_vs_set_offset_memb_mess();
-                        num_bytes          += SP_get_vs_set_size_offset_vs_set();
-                        vs_set_size_ptr     = &mess[num_bytes];
-                        num_bytes          += SP_get_vs_set_members_offset_vs_set();
-			vs_set_members      = &mess[num_bytes];
-
 			printf("Received REGULAR membership for group %s with %d members, where I am member %d:\n",
 				sender, num_groups, mess_type );
 			for( i=0; i < num_groups; i++ )
 				printf("\t%s\n", &target_groups[i][0] );
-			printf("grp id is %d %d %d\n",grp_id_ptr->id[0], grp_id_ptr->id[1], grp_id_ptr->id[2] );
+			printf("grp id is %d %d %d\n",memb_info.gid.id[0], memb_info.gid.id[1], memb_info.gid.id[2] );
 
 			if( Is_caused_join_mess( service_type ) )
 			{
-				printf("Due to the JOIN of %s\n", vs_set_members );
+				printf("Due to the JOIN of %s\n", memb_info.changed_member );
 			}else if( Is_caused_leave_mess( service_type ) ){
-				printf("Due to the LEAVE of %s\n", vs_set_members);
+				printf("Due to the LEAVE of %s\n", memb_info.changed_member );
 			}else if( Is_caused_disconnect_mess( service_type ) ){
-				printf("Due to the DISCONNECT of %s\n", vs_set_members );
+				printf("Due to the DISCONNECT of %s\n", memb_info.changed_member );
 			}else if( Is_caused_network_mess( service_type ) ){
-				printf("Due to NETWORK change with %u VS sets\n", *num_vs_sets_ptr);
-                                for( i = 0; i < *num_vs_sets_ptr; ++i )
+				printf("Due to NETWORK change with %u VS sets\n", memb_info.num_vs_sets);
+                                num_vs_sets = SP_get_vs_sets_info( mess, &vssets[0], MAX_VSSETS, &my_vsset_index );
+                                if (num_vs_sets < 0) {
+                                        printf("BUG: membership message has more then %d vs sets. Recompile with larger MAX_VSSETS\n", MAX_VSSETS);
+                                        SP_error( num_vs_sets );
+                                        exit( 1 );
+                                }
+                                for( i = 0; i < num_vs_sets; i++ )
                                 {
-                                        if( 0 != i )
-                                        {
-                                                vs_set_size_ptr = vs_set_members;
-                                                vs_set_members += sizeof(int32u);
+                                        printf("%s VS set %d has %u members:\n",
+                                               (i  == my_vsset_index) ?
+                                               ("LOCAL") : ("OTHER"), i, vssets[i].num_members );
+                                        ret = SP_get_vs_set_members(mess, &vssets[i], members, MAX_MEMBERS);
+                                        if (ret < 0) {
+                                                printf("VS Set has more then %d members. Recompile with larger MAX_MEMBERS\n", MAX_MEMBERS);
+                                                SP_error( ret );
+                                                exit( 1 );
                                         }
-                                        memcpy( &vs_set_size, vs_set_size_ptr, sizeof(int32u) );
-                                        printf("%s VS set %d has %d members:\n",
-                                               (vs_set_size_ptr - mess == local_vs_set_offset) ?
-                                               ("LOCAL") : ("OTHER"), i, vs_set_size );
-                                        for( j = 0; j < vs_set_size; j++, vs_set_members += MAX_GROUP_NAME )
-                                                printf("\t%s\n", vs_set_members );
+                                        for( j = 0; j < vssets[i].num_members; j++ )
+                                                printf("\t%s\n", members[j] );
                                 }
 			}
 		}else if( Is_transition_mess(   service_type ) ) {

Modified: trunk/include/sp.h
===================================================================
--- trunk/include/sp.h	2006-02-21 05:26:22 UTC (rev 314)
+++ trunk/include/sp.h	2006-03-01 13:12:14 UTC (rev 315)
@@ -148,7 +148,18 @@
 	int32		id[3];
 } group_id;
 
+typedef struct dummy_vs_set_info {
+        unsigned int num_members;
+        unsigned int members_offset;  /* offset from beginning of msg body*/
+} vs_set_info;
 
+typedef struct dummy_membership_info {
+        group_id     gid;
+        char         changed_member[MAX_GROUP_NAME]; /* filled in on CAUSED_BY_JOIN, CAUSED_BY_LEAVE or CAUSED_BY_DISCONNECT only */
+        unsigned int num_vs_sets;
+        vs_set_info  my_vs_set;
+} membership_info;
+
 #include "sp_events.h"
 #include "sp_func.h"
 #ifdef __cplusplus

Modified: trunk/include/sp_func.h
===================================================================
--- trunk/include/sp_func.h	2006-02-21 05:26:22 UTC (rev 314)
+++ trunk/include/sp_func.h	2006-03-01 13:12:14 UTC (rev 315)
@@ -93,21 +93,31 @@
 			 int16 *mess_type, int *endian_mismatch,
 			 scatter *scat_mess );
 
-/* FIXME: We could make something much friendlier here. */
-/* returns offset in memb. message of gid (group id), num_vs_sets,
- * offset to local vs_set, and first vs_set */
-int     SP_get_gid_offset_memb_mess(void);
-int     SP_get_num_vs_sets_offset_memb_mess(void);
-int     SP_get_first_vs_set_offset_memb_mess(void);
-/* returns offset into the buffer for a vs_set of the number of
- * members in the vs_set. */
-int     SP_get_vs_set_size_offset_vs_set(void);
-int     SP_get_vs_set_members_offset_vs_set(void);
-/* returns value from regular membership message */
-int     SP_get_offset_to_local_vs_set_offset(void);
-int     SP_get_local_vs_set_offset_memb_mess( char *reg_memb_mess );  
-int     SP_get_local_vs_set_offset_memb_scat( const scatter *reg_memb_scat );
+/* get membership info from a message */
+int     SP_get_memb_info( const char *memb_mess, 
+                          const service service_type,
+                          membership_info *memb_info);
+int     SP_get_vs_sets_info( const char *memb_mess,
+                             vs_set_info *vs_sets, 
+                             int num_vs_sets,
+                             unsigned int *my_vs_set_index);
+int     SP_get_vs_set_members( const char *memb_mess, 
+                               const vs_set_info *vs_set, 
+                               char member_names[][MAX_GROUP_NAME],
+                               int member_names_len);
 
+int     SP_scat_get_memb_info( const scatter *memb_mess_scat, 
+                               const service service_type,
+                               membership_info *memb_info);
+int     SP_scat_get_vs_sets_info( const scatter *memb_mess_scat, 
+                                  vs_set_info *vs_sets, 
+                                  int num_vs_sets,
+                                  unsigned int *my_vs_set_index);
+int     SP_scat_get_vs_set_members( const scatter *memb_mess_scat, 
+                                    const vs_set_info *vs_set, 
+                                    char member_names[][MAX_GROUP_NAME],
+                                    int member_names_len);
+
 int	SP_poll( mailbox mbox );
 
 int	SP_equal_group_ids( group_id g1, group_id g2 );

Modified: trunk/libspread/fl.c
===================================================================
--- trunk/libspread/fl.c	2006-02-21 05:26:22 UTC (rev 314)
+++ trunk/libspread/fl.c	2006-03-01 13:12:14 UTC (rev 315)
@@ -1432,13 +1432,12 @@
 	}
       }
     } else if (Is_reg_memb_mess(*m->serv_type)) {
+      membership_info m_info;
       /* if its a regular membership message read the group id out of the msg */
       assert(m->ret >= sizeof(group_id) + sizeof(int) + MAX_GROUP_NAME);    /* ensure received */
-      err = scatp_begin(&pos, scat);
-      assert(err == 0);
-      err = scatp_jforward(&pos, SP_get_gid_offset_memb_mess());
-      assert(err == SP_get_gid_offset_memb_mess());
-      err = scatp_cpy1((char*) &m->dst_gid, &pos, sizeof(group_id));       /* copy out new gid */
+      err = SP_scat_get_memb_info( scat, *m->serv_type, &m_info);
+
+      memcpy(&m->dst_gid, &m_info.gid, sizeof(group_id) );
       assert(err == sizeof(group_id));                             /* already endian corrected */
       DEBUG(std_stkfprintf(stderr, 0, "Recvd a SP reg memb mess: New SP gid is %d %d %d\n", 
 			   m->dst_gid.id[0], m->dst_gid.id[1], m->dst_gid.id[2]));
@@ -1978,38 +1977,22 @@
 
 static char*
 determine_leavers(stdhash *leavers, view *last_sp_view, gc_recv_mess *m) {
-  char     delta[MAX_GROUP_NAME], *delta_ptr = delta, *ret = 0;
+  char     *ret = 0;
   int      i;
-  scatter *scat;
-  scatp    pos;
   long     err;
-  stduint32   offset;
   stduint32   num_membs;
+  membership_info       m_info;
+  char    (*members)[MAX_GROUP_NAME];
 
   DEBUG(std_stkfprintf(stderr, 1, "determine_leavers: old gid %d %d %d -> new gid %d %d %d\n", 
 		       last_sp_view->gid.id[0], last_sp_view->gid.id[1], 
 		       last_sp_view->gid.id[2], m->dst_gid.id[0], m->dst_gid.id[1],
 		       m->dst_gid.id[2]));
 
-  get_scat_info(m, &i, &scat);                                   /* i is a dummy variable here */
+  err = SP_scat_get_memb_info( m->scat_mess, *m->serv_type, &m_info);
+  assert(err == 1);
+  num_membs = m_info.my_vs_set.num_members;
 
-  err = scatp_set(&pos, scat, SP_get_offset_to_local_vs_set_offset(), SEEK_SET);
-  assert(err == 0);
-
-  err = scatp_cpy1((char*) &offset, &pos, sizeof(stduint32));
-  assert(err == sizeof(stduint32));
-
-  offset += SP_get_first_vs_set_offset_memb_mess();                     /* get local VS offset */
-
-  err = scatp_set(&pos, scat, offset, SEEK_SET);
-  assert(err == offset);
-
-  err = scatp_cpy1((char*) &num_membs, &pos, sizeof(stduint32));         /* read out num membs */
-  assert(err == sizeof(stduint32));
-
-  err = scatp_jforward(&pos, sizeof(stduint32));                          /* advance to vs_set */
-  assert(err == sizeof(stduint32));
-
   if (!Is_caused_network_mess(*m->serv_type)) {               /* join, leave, or disconnection */
     assert(num_membs == 1);
 
@@ -2018,13 +2001,11 @@
     stdhash_construct(leavers, sizeof(char*), 0, 
 		      group_name_ptr_cmp, group_name_ptr_hashcode, 0);
     
-    err = scatp_cpy1(delta, &pos, MAX_GROUP_NAME);      /* read out joiner/leaver/disconnector */
-    assert(err == MAX_GROUP_NAME);
-    delta[MAX_GROUP_NAME - 1] = 0;                                  /* ensure null termination */
 
     if ((ret = (char*) malloc(MAX_GROUP_NAME)) == 0)
       stderr_abort("(%s, %d): malloc(%d)\n", __FILE__, __LINE__, MAX_GROUP_NAME);
-    strncpy(ret, delta, MAX_GROUP_NAME);                    /* strndup delta member for return */
+    memcpy( ret, m_info.changed_member, MAX_GROUP_NAME); /* read out joiner/leaver/disconnector */
+    ret[MAX_GROUP_NAME - 1] = 0;                                  /* ensure null termination */
 
     DEBUG(std_stkfprintf(stderr, 0, "delta memb: '%s'\n", delta));
     if (!Is_caused_join_mess(*m->serv_type)) {                   /* insert leaver into leavers */
@@ -2037,13 +2018,14 @@
     stdhash_copy_construct(leavers, &last_sp_view->orig_membs);     /* copy last SP membership */
 
     DEBUG(std_stkfprintf(stderr, 0, "Num_membs %u\n", num_membs));
+    if ((members = (char (*)[MAX_GROUP_NAME])malloc(num_membs * sizeof( *members ) ) ) == 0)
+      stderr_abort("(%s, %d): malloc(%d)\n", __FILE__, __LINE__, num_membs * MAX_GROUP_NAME);
+    err = SP_scat_get_vs_set_members( m->scat_mess, &m_info.my_vs_set, members, num_membs);
+    assert(err == num_membs);
     for (i = 0; i < num_membs; ++i) {        /* remove members that came with me: leaves who left */
-      err = scatp_adv_cpy1(&delta_ptr, &pos, MAX_GROUP_NAME, 0, 1);
-      assert(err == MAX_GROUP_NAME);
-
-      delta[MAX_GROUP_NAME - 1] = 0;                                /* ensure null termination */
+      members[i][MAX_GROUP_NAME -1] = 0;
       err = stdhash_size(leavers);
-      stdhash_erase_key(leavers, &delta_ptr);
+      stdhash_erase_key(leavers, &(members[i][0]));
       assert(err == stdhash_size(leavers) + 1);
     }
   }

Modified: trunk/libspread/sp.c
===================================================================
--- trunk/libspread/sp.c	2006-02-21 05:26:22 UTC (rev 314)
+++ trunk/libspread/sp.c	2006-03-01 13:12:14 UTC (rev 315)
@@ -67,9 +67,23 @@
 #include "sess_types.h"
 #include "scatter.h"
 #include "alarm.h"
-#include "sp_func.h"
 #include "acm.h"
 
+/* SP functions need these types, but internal headers do not */
+typedef struct dummy_vs_set_info {
+        unsigned int num_members;
+        unsigned int members_offset;  /* offset from beginning of msg body*/
+} vs_set_info;
+
+typedef struct dummy_membership_info {
+        group_id     gid;
+        char         changed_member[MAX_GROUP_NAME]; /* filled in on CAUSED_BY_JOIN, CAUSED_BY_LEAVE or CAUSED_BY_DISCONNECT only */
+        unsigned int num_vs_sets;
+        vs_set_info  my_vs_set;
+} membership_info;
+
+#include "sp_func.h"
+
 enum sp_sess_state {
     SESS_UNUSED,
     SESS_ACTIVE,
@@ -1764,6 +1778,9 @@
 	else return( 0 );
 }
 
+/* get membership info from a message */
+
+/* internal only for now -- maybe static? */
 int     SP_get_gid_offset_memb_mess(void) 
 {
         return 0;
@@ -1794,6 +1811,199 @@
         return sizeof(int32u);
 }
 
+/* public functions */
+int     SP_get_memb_info( const char *memb_mess, 
+                          const service service_type,
+                          membership_info *memb_info) 
+{
+        int32u my_vs_offset;
+
+        if ( !Is_membership_mess( service_type ) )
+                return(ILLEGAL_MESSAGE);
+
+        memcpy( &memb_info->gid, &memb_mess[SP_get_gid_offset_memb_mess()], sizeof(group_id));
+        
+        if ( Is_reg_memb_mess( service_type ) )
+        {
+                if( Is_caused_join_mess( service_type ) || 
+                    Is_caused_leave_mess( service_type ) ||
+                    Is_caused_disconnect_mess( service_type ) )
+                {
+                        memcpy(memb_info->changed_member, &memb_mess[SP_get_first_vs_set_offset_memb_mess()+SP_get_vs_set_members_offset_vs_set()], MAX_GROUP_NAME);
+                } else if( Is_caused_network_mess( service_type ) )
+                {
+                        memset(memb_info->changed_member, 0, MAX_GROUP_NAME);
+                }
+                memb_info->num_vs_sets = *((int32u *)&memb_mess[SP_get_num_vs_sets_offset_memb_mess()]);
+                my_vs_offset = *((int32u *)&memb_mess[SP_get_offset_to_local_vs_set_offset()]);
+                my_vs_offset += SP_get_first_vs_set_offset_memb_mess();
+                memb_info->my_vs_set.num_members = *((int32u *)&memb_mess[my_vs_offset + SP_get_vs_set_size_offset_vs_set()]);
+                memb_info->my_vs_set.members_offset  = my_vs_offset + SP_get_vs_set_members_offset_vs_set();
+        } else {
+                /* Is transitional */
+                memb_info->num_vs_sets = 0;
+                memb_info->my_vs_set.num_members = 0;
+                memb_info->my_vs_set.members_offset  = 0;
+        }
+        return( 1 );
+}
+
+
+int     SP_get_vs_sets_info( const char *memb_mess, 
+                             vs_set_info *vs_sets, 
+                             int num_vs_sets,
+                             unsigned int *my_vs_set_index)
+{
+        unsigned int actual_num_vs_sets;
+        unsigned int memb_offset, local_vs_set_offset;
+        int i;
+
+        actual_num_vs_sets = *((int32u *)&memb_mess[SP_get_num_vs_sets_offset_memb_mess()]);
+
+        if (num_vs_sets < actual_num_vs_sets)
+                return(BUFFER_TOO_SHORT);
+
+        local_vs_set_offset = *((int32u *)&memb_mess[SP_get_offset_to_local_vs_set_offset()]);
+        local_vs_set_offset += SP_get_first_vs_set_offset_memb_mess();
+        memb_offset = SP_get_first_vs_set_offset_memb_mess();
+
+        for ( i=0; i < num_vs_sets; i++, vs_sets++ )
+        {
+                if (memb_offset == local_vs_set_offset)
+                        *my_vs_set_index = i;
+                vs_sets->num_members = *(int32u *)&memb_mess[memb_offset];
+                memb_offset += SP_get_vs_set_members_offset_vs_set();
+                vs_sets->members_offset = memb_offset;
+                memb_offset += (vs_sets->num_members * MAX_GROUP_NAME) ;
+        }
+        return ( actual_num_vs_sets );
+}
+
+int     SP_get_vs_set_members( const char *memb_mess, 
+                               const vs_set_info *vs_set, 
+                               char member_names[][MAX_GROUP_NAME],
+                               int member_names_len)
+{
+        int i;
+        const char *members_ptr;
+
+        if (member_names_len < vs_set->num_members)
+                return(BUFFER_TOO_SHORT);
+
+        members_ptr = &memb_mess[vs_set->members_offset];
+        for ( i=0; i < vs_set->num_members; i++, members_ptr += MAX_GROUP_NAME )
+        {
+                memcpy(&member_names[i][0], members_ptr, MAX_GROUP_NAME);
+        }
+        return( vs_set->num_members );
+}
+
+static  void    scat_read(void *dest_ptr, const scatter *msg, int start_byte, int copy_size)
+{
+        int scat, scat_index, bytes_index, bytes_to_copy;
+
+        scat = 0;
+        scat_index = 0;
+        while(start_byte > msg->elements[scat].len) 
+        {
+                scat++;
+                start_byte -= msg->elements[scat].len;
+        }
+        scat_index = start_byte;
+        for( bytes_index = 0; bytes_index < copy_size ; bytes_index += bytes_to_copy )
+        {
+                bytes_to_copy = copy_size - bytes_index;
+                if( bytes_to_copy > msg->elements[scat].len - scat_index )
+                        bytes_to_copy = msg->elements[scat].len - scat_index;
+                memcpy( dest_ptr, &(msg->elements[scat].buf[scat_index]), bytes_to_copy );
+                if( bytes_to_copy == msg->elements[scat].len - scat_index )
+                {
+                        scat_index = 0;
+                        ++scat;
+                } else {
+                        scat_index = bytes_to_copy;
+                }
+        }
+}
+
+int     SP_scat_get_memb_info( const scatter *memb_mess_scat, 
+                               const service service_type,
+                               membership_info *memb_info)
+{
+        int32u my_vs_offset;
+
+        if ( !Is_membership_mess( service_type ) )
+                return(ILLEGAL_MESSAGE);
+
+        scat_read( &memb_info->gid, memb_mess_scat, 0, sizeof( group_id ));
+        
+        if ( Is_reg_memb_mess( service_type ) )
+        {
+                if( Is_caused_join_mess( service_type ) || 
+                    Is_caused_leave_mess( service_type ) ||
+                    Is_caused_disconnect_mess( service_type ) )
+                {
+                        scat_read(memb_info->changed_member, memb_mess_scat, SP_get_first_vs_set_offset_memb_mess()+SP_get_vs_set_members_offset_vs_set(), MAX_GROUP_NAME );
+                } else if( Is_caused_network_mess( service_type ) )
+                {
+                        memset(memb_info->changed_member, 0, MAX_GROUP_NAME);
+                }
+                scat_read( &(memb_info->num_vs_sets), memb_mess_scat, SP_get_num_vs_sets_offset_memb_mess(), sizeof( int32u ) );
+                scat_read( &my_vs_offset, memb_mess_scat, SP_get_offset_to_local_vs_set_offset(), sizeof( int32u ));
+                my_vs_offset += SP_get_first_vs_set_offset_memb_mess();
+                scat_read( &(memb_info->my_vs_set.num_members), memb_mess_scat,  my_vs_offset + SP_get_vs_set_size_offset_vs_set(), sizeof( int32u ) );
+                memb_info->my_vs_set.members_offset  = my_vs_offset + SP_get_vs_set_members_offset_vs_set();
+        } else {
+                /* Is transitional */
+                memb_info->num_vs_sets = 0;
+                memb_info->my_vs_set.num_members = 0;
+                memb_info->my_vs_set.members_offset  = 0;
+        }
+        return( 1 );
+}
+int     SP_scat_get_vs_sets_info( const scatter *memb_mess_scat, 
+                                  vs_set_info *vs_sets, 
+                                  int num_vs_sets,
+                                  unsigned int *my_vs_set_index)
+{
+        unsigned int actual_num_vs_sets;
+        unsigned int memb_offset, local_vs_set_offset;
+        int i;
+
+        scat_read( &actual_num_vs_sets, memb_mess_scat, SP_get_num_vs_sets_offset_memb_mess(), sizeof( int32u ) );
+
+        if (num_vs_sets < actual_num_vs_sets)
+                return(BUFFER_TOO_SHORT);
+
+        scat_read( &local_vs_set_offset, memb_mess_scat, SP_get_offset_to_local_vs_set_offset(), sizeof( int32u ) );
+        local_vs_set_offset += SP_get_first_vs_set_offset_memb_mess();
+        memb_offset = SP_get_first_vs_set_offset_memb_mess();
+
+        for ( i=0; i < num_vs_sets; i++, vs_sets++ )
+        {
+                if (memb_offset == local_vs_set_offset)
+                        *my_vs_set_index = i;
+
+                scat_read(&(vs_sets->num_members), memb_mess_scat, memb_offset, sizeof( int32u ) );
+                memb_offset += SP_get_vs_set_members_offset_vs_set();
+                vs_sets->members_offset = memb_offset;
+                memb_offset += (vs_sets->num_members * MAX_GROUP_NAME) ;
+        }
+        return ( actual_num_vs_sets );
+}
+int     SP_scat_get_vs_set_members( const scatter *memb_mess_scat, 
+                                    const vs_set_info *vs_set, 
+                                    char member_names[][MAX_GROUP_NAME],
+                                    int member_names_len)
+{
+        if (member_names_len < vs_set->num_members)
+                return(BUFFER_TOO_SHORT);
+
+        scat_read( member_names, memb_mess_scat, vs_set->members_offset, vs_set->num_members * MAX_GROUP_NAME);
+        return( vs_set->num_members );
+}
+
+
 int     SP_get_local_vs_set_offset_memb_mess( char *reg_memb_mess )
 {
         int32u offset;




More information about the Spread-cvs mailing list