1
1

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.
Этот коммит содержится в:
Graham Fagg 2004-08-18 23:18:25 +00:00
родитель 1d3e06bb8a
Коммит 720156b50d
3 изменённых файлов: 199 добавлений и 0 удалений

Просмотреть файл

@ -501,6 +501,7 @@ return (OMPI_SUCCESS);
switch(type) { switch(type) {
case OMPI_BYTE: case OMPI_BYTE:
memcpy(dest, src, n); memcpy(dest, src, n);
break;
case OMPI_PACKED: case OMPI_PACKED:
return OMPI_ERROR; return OMPI_ERROR;
case OMPI_INT16: case OMPI_INT16:
@ -536,3 +537,104 @@ return (OMPI_SUCCESS);
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); 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) #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 test5(void); /* verify unpack */
static bool test6(void); /* verify free */ static bool test6(void); /* verify free */
static bool test7(void); /* verify preallocated buffer init, pack and unpack */ 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[]) int main (int argc, char* argv[])
{ {
@ -85,6 +86,13 @@ int main (int argc, char* argv[])
test_failure("ompi_pack test7 failed"); test_failure("ompi_pack test7 failed");
} }
if (test8()) {
test_success();
}
else {
test_failure("ompi_pack test8 failed");
}
/* if (testN()) { */ /* if (testN()) { */
/* test_success(); */ /* test_success(); */
@ -264,6 +272,63 @@ static bool test7(void) /* verify preallocated buffer init, pack and unpa
return (true); 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 dump_buf (ompi_buffer_t buf) */
/* { */ /* { */
/* int rc, i, out; */ /* int rc, i, out; */