Added new pack and unpack string functions. These are mainly used by RTE (NS/GPR etc).
- unpack string allocates memory for user removing need to know/set max string lengths - fixed missing 'break' in case statement thanks to unit test yet again! - updated unit test ompi_pack (test8) - will remove old OMPI_STRING type and support shortly after checking for usage This commit was SVN r2219.
Этот коммит содержится в:
родитель
1d3e06bb8a
Коммит
720156b50d
102
src/util/pack.c
102
src/util/pack.c
@ -501,6 +501,7 @@ return (OMPI_SUCCESS);
|
||||
switch(type) {
|
||||
case OMPI_BYTE:
|
||||
memcpy(dest, src, n);
|
||||
break;
|
||||
case OMPI_PACKED:
|
||||
return OMPI_ERROR;
|
||||
case OMPI_INT16:
|
||||
@ -536,3 +537,104 @@ return (OMPI_SUCCESS);
|
||||
return OMPI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* fuctions to handle strings, which use the length arguments differently to normal pack routines
|
||||
*
|
||||
* @param buffer the destination for the packed data
|
||||
* @param str pointer to start of NULL terminated string
|
||||
*
|
||||
* @retval OMPI_SUCCESS
|
||||
* @retval OMPI_ERROR
|
||||
*
|
||||
*/
|
||||
|
||||
int ompi_pack_string (ompi_buffer_t buffer, char *str)
|
||||
{
|
||||
uint32_t op_size=0;
|
||||
int rc;
|
||||
|
||||
if (!str) {
|
||||
return OMPI_ERROR;
|
||||
}
|
||||
|
||||
if (!buffer) { return (OMPI_ERROR); }
|
||||
|
||||
op_size = (uint32_t) strlen (str);
|
||||
|
||||
/* a packed string consists of a packed length, and the non terminated string */
|
||||
rc = ompi_pack(buffer, (void*) &op_size, 1, OMPI_INT32);
|
||||
|
||||
if (OMPI_ERROR==rc) { return (rc); }
|
||||
|
||||
if (op_size>0) {
|
||||
rc = ompi_pack(buffer, (void*) str, op_size, OMPI_BYTE);
|
||||
}
|
||||
|
||||
return (rc);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function unpacks a string from the buffer. This routine ALLOCATES memory
|
||||
* for this string. Allocating means users DO NOT need to define max string lengths for any
|
||||
* strings they pass (allowing the use of unrestricted naming in the GPR f.e.)
|
||||
* if this string is zero length we return a NULL pointer
|
||||
*
|
||||
* @param buffer the source of the packed string data
|
||||
* @param pointer to a character pointer of the unpacked string or NULL for zero length
|
||||
* string
|
||||
* @param type the type of the data to unpack
|
||||
*
|
||||
* @retval number of characters unpacked (INCLUDING the NULL character)
|
||||
* If this value is '0' this indicates an empty string was passed.
|
||||
* @retval OMPI_ERROR
|
||||
*
|
||||
*/
|
||||
|
||||
int ompi_unpack_string(ompi_buffer_t buffer, char ** str)
|
||||
{
|
||||
char *inptr;
|
||||
uint32_t inlen=0;
|
||||
uint32_t outlen=0; /* always inlen+1 I hope */
|
||||
int rc;
|
||||
|
||||
if (!str) {
|
||||
return OMPI_ERROR;
|
||||
}
|
||||
|
||||
if (!buffer) { return (OMPI_ERROR); }
|
||||
|
||||
/* first unpack the length of the packed string */
|
||||
|
||||
rc = ompi_unpack (buffer, (void*) &inlen, 1, OMPI_INT32);
|
||||
|
||||
if (OMPI_ERROR==rc) { return (rc); }
|
||||
|
||||
if (!inlen) { /* if we have a zero length string... set str pointer to NULL and return 0 length */
|
||||
*str = NULL;
|
||||
return (0);
|
||||
}
|
||||
else {
|
||||
outlen = inlen +1;
|
||||
}
|
||||
|
||||
/* no zero length string, so allocate memory for it */
|
||||
inptr = (char*) calloc (outlen, 1);
|
||||
|
||||
if (!inptr) { return (OMPI_ERROR); }
|
||||
|
||||
/* have memory, unpack as byte, null terminate and then return */
|
||||
rc = ompi_unpack (buffer, (void*) inptr, inlen, OMPI_BYTE);
|
||||
|
||||
if (OMPI_ERROR==rc) { return (rc); }
|
||||
|
||||
inptr[inlen] = '\0'; /* NULL terminate */
|
||||
|
||||
*str = (char*) inptr; /* copy the string over */
|
||||
|
||||
return (outlen);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -160,6 +160,38 @@ extern "C" {
|
||||
int ompi_unpack(ompi_buffer_t buffer, void * dest, size_t n, ompi_pack_type_t type);
|
||||
|
||||
|
||||
/*
|
||||
* fuctions to handle strings, which use the length arguments different
|
||||
*
|
||||
* @param buffer the destination for the packed data
|
||||
* @param str pointer to start of NULL terminated string
|
||||
*
|
||||
* @retval OMPI_SUCCESS
|
||||
* @retval OMPI_ERROR
|
||||
*
|
||||
*/
|
||||
|
||||
int ompi_pack_string (ompi_buffer_t buffer, char *str);
|
||||
|
||||
/**
|
||||
* This function unpacks a string from the buffer. This routine ALLOCATES memory
|
||||
* for this string. Allocating means users DO NOT need to define max string lengths for any
|
||||
* strings they pass (allowing the use of unrestricted naming in the GPR f.e.)
|
||||
* if this string is zero length we return a NULL pointer
|
||||
*
|
||||
* @param buffer the source of the packed string data
|
||||
* @param pointer to a character pointer of the unpacked string or NULL for zero length string
|
||||
* @param type the type of the data to unpack
|
||||
*
|
||||
* @retval number of characters unpacked (INCLUDING the NULL character)
|
||||
* If this value is '0' this indicates an empty string was passed.
|
||||
* @retval OMPI_ERROR
|
||||
*
|
||||
*/
|
||||
int ompi_unpack_string(ompi_buffer_t buffer, char ** str);
|
||||
|
||||
|
||||
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ static bool test4(void); /* verify pack a packed buffer */
|
||||
static bool test5(void); /* verify unpack */
|
||||
static bool test6(void); /* verify free */
|
||||
static bool test7(void); /* verify preallocated buffer init, pack and unpack */
|
||||
static bool test8(void); /* verify string pack and unpack */
|
||||
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
@ -85,6 +86,13 @@ int main (int argc, char* argv[])
|
||||
test_failure("ompi_pack test7 failed");
|
||||
}
|
||||
|
||||
if (test8()) {
|
||||
test_success();
|
||||
}
|
||||
else {
|
||||
test_failure("ompi_pack test8 failed");
|
||||
}
|
||||
|
||||
|
||||
/* if (testN()) { */
|
||||
/* test_success(); */
|
||||
@ -264,6 +272,63 @@ static bool test7(void) /* verify preallocated buffer init, pack and unpa
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
||||
static bool test8(void) /* verify string pack and unpack */
|
||||
{
|
||||
|
||||
int rc;
|
||||
char *str1;
|
||||
char *str2;
|
||||
|
||||
rc = ompi_buffer_init (&bufA, 0);
|
||||
if (OMPI_ERROR==rc) { test_comment ("ompi_buffer_init failed"); return(false);}
|
||||
|
||||
rc = ompi_buffer_init (&bufB, 10);
|
||||
if (OMPI_ERROR==rc) { test_comment ("ompi_buffer_init failed"); return(false);}
|
||||
|
||||
rc = ompi_buffer_init (&bufC, 16);
|
||||
if (OMPI_ERROR==rc) { test_comment ("ompi_buffer_init failed"); return(false);}
|
||||
|
||||
rc = ompi_pack_string (bufA, "HELLO ");
|
||||
if (OMPI_ERROR==rc) { test_comment ("ompi_pack_string failed"); return(false);}
|
||||
|
||||
rc = ompi_pack_string (bufB, "WORLD!");
|
||||
if (OMPI_ERROR==rc) { test_comment ("ompi_pack_string failed"); return(false);}
|
||||
|
||||
rc = ompi_pack (bufC, bufA, 1, OMPI_PACKED);
|
||||
if (OMPI_ERROR==rc) { test_comment ("ompi_pack failed"); return(false);}
|
||||
rc = ompi_pack (bufC, bufB, 1, OMPI_PACKED);
|
||||
if (OMPI_ERROR==rc) { test_comment ("ompi_pack failed"); return(false);}
|
||||
|
||||
/* we now have a buffer with two strings in it */
|
||||
rc = ompi_unpack_string (bufC, &str1);
|
||||
if (OMPI_ERROR==rc) { test_comment ("ompi_pack_string failed"); return(false);}
|
||||
|
||||
rc = strcmp ("HELLO ", str1);
|
||||
if (rc) { test_comment ("strcmp returns no zero value."); return (false); }
|
||||
|
||||
rc = ompi_unpack_string (bufC, &str2);
|
||||
if (OMPI_ERROR==rc) { test_comment ("ompi_pack_string failed"); return(false);}
|
||||
|
||||
rc = strcmp ("WORLD!", str2);
|
||||
if (rc) { test_comment ("strcmp returns no zero value."); return (false); }
|
||||
|
||||
|
||||
rc = ompi_buffer_free (bufA);
|
||||
if (OMPI_ERROR==rc) { test_comment ("ompi_buffer_free failed"); return(false);}
|
||||
|
||||
rc = ompi_buffer_free (bufB);
|
||||
if (OMPI_ERROR==rc) { test_comment ("ompi_buffer_free failed"); return(false);}
|
||||
|
||||
rc = ompi_buffer_free (bufC);
|
||||
if (OMPI_ERROR==rc) { test_comment ("ompi_buffer_free failed"); return(false);}
|
||||
|
||||
if (str1) { free (str1); }
|
||||
if (str2) { free (str2); }
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
/* int dump_buf (ompi_buffer_t buf) */
|
||||
/* { */
|
||||
/* int rc, i, out; */
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user