📄 sflexdr.c
字号:
case 'l': /* Signed long (32-bit) */
case 'q': /* 4-byte unsigned value */
qbyte_value = htonl (va_arg (argptr, qbyte));
ASSERT (used_size + 4 <= buffer-> size);
*(byte *) target++ = *((byte *) &qbyte_value);
*(byte *) target++ = *((byte *) &qbyte_value + 1);
*(byte *) target++ = *((byte *) &qbyte_value + 2);
*(byte *) target++ = *((byte *) &qbyte_value + 3);
break;
case 's': /* Null-terminated string */
string = va_arg (argptr, char *);
if (string)
{
ASSERT (used_size + strlen (string) + 1 <= buffer-> size);
strcpy ((char *) target, string);
target += strlen (string) + 1;
}
else /* Store NULL as single null byte */
{
ASSERT (used_size + 1 <= buffer-> size);
*(byte *) target++ = 0;
}
break;
case 'm': /* Memory descriptor size */
memory_size = va_arg (argptr, int);
ASSERT (used_size + 2 + memory_size <= buffer-> size);
dbyte_value = htons ((dbyte) memory_size);
*(byte *) target++ = *((byte *) &dbyte_value);
*(byte *) target++ = *((byte *) &dbyte_value + 1);
break;
case 'M': /* Memory descriptor body */
block = va_arg (argptr, byte *);
if (block)
{
memcpy (target, block, (size_t) memory_size);
target += (size_t) memory_size;
}
else
ASSERT (memory_size == 0);
break;
case 'h': /* Huge memory descriptor size */
memory_size = va_arg (argptr, qbyte);
ASSERT (used_size + 4 + memory_size <= buffer-> size);
qbyte_value = htonl (memory_size);
*(byte *) target++ = *((byte *) &qbyte_value);
*(byte *) target++ = *((byte *) &qbyte_value + 1);
*(byte *) target++ = *((byte *) &qbyte_value + 2);
*(byte *) target++ = *((byte *) &qbyte_value + 3);
break;
case 'H': /* Huge memory descriptor body */
block = va_arg (argptr, byte *);
if (block)
{
memcpy (target, block, (size_t) memory_size);
target += (size_t) memory_size;
}
else
ASSERT (memory_size == 0);
break;
}
}
va_end (argptr); /* End variable arguments list */
return ((int) (target - buffer-> data));
}
/* ---------------------------------------------------------------------[<]-
Function: exdr_read
Synopsis: Unpacks a buffer prepared by exdr_write() into as set of data
items as specified by a format string. See exdr_write() for the syntax
of the format string. Each format sequence corresponds to one item in
in the list which must be specified as an address. Target strings and
memory blocks must be large enough to hold the returned data: target
strings and blocks can also be null, in which case the function calls
mem_alloc to allocate heap memory. Note that you must supply a pointer
to the string or memory block address, not the address itself. It is a
common error to pass the address of a static block - see the example
below for the *right* way to do it. Any of the argument addresses can
be NULL, in which case that field is ignored. This is useful to get a
few selected fields out of a message. Errors in the argument list can
cause memory corruption and unpredictable program results.
If a memory allocation fails, all previous memory allocations are "rolled
back" and the function returns the value -1.
Return codes: 0 - normal
-1 - memory allocation failed
Examples:
char *string = NULL;
byte buffer [1000];
byte *buffaddr = buffer;
int value, length;
exdr_read (buffer, "qdsmM", NULL, &value, &string, &length, &buffaddr);
---------------------------------------------------------------------[>]-*/
int
exdr_read (const byte *buffer, const char *format, ...)
{
MEMTRN
*memtrn; /* Memory transaction */
va_list
argptr; /* Argument list pointer */
void
*target; /* Source data item address */
dbyte
string_size, /* String size */
dbyte_value; /* Network format dbyte value */
qbyte
memory_size = 0, /* Memory descriptor size value */
qbyte_value; /* Network format qbyte value */
ASSERT (buffer);
ASSERT (format);
memtrn = mem_new_trans ();
va_start (argptr, format); /* Start variable arguments list */
while (*format)
{
target = va_arg (argptr, void *);
switch (*format++)
{
case 'c': /* Character */
case 'b': /* Single byte */
if (target)
*(byte *) target = *(byte *) buffer;
buffer += 1;
break;
case 'd': /* Signed short integer */
case 'w': /* Unsigned short integer */
case 'B': /* Bool */
*((byte *) &dbyte_value) = *(byte *) buffer++;
*((byte *) &dbyte_value + 1) = *(byte *) buffer++;
if (target)
*(dbyte *) target = ntohs (dbyte_value);
break;
case 'l': /* Signed long (32-bit) */
case 'q': /* 4-byte unsigned value */
*((byte *) &qbyte_value) = *(byte *) buffer++;
*((byte *) &qbyte_value + 1) = *(byte *) buffer++;
*((byte *) &qbyte_value + 2) = *(byte *) buffer++;
*((byte *) &qbyte_value + 3) = *(byte *) buffer++;
if (target)
*(qbyte *) target = ntohl (qbyte_value);
break;
case 's': /* Null-terminated string */
string_size = strlen ((char *) buffer) + 1;
if (target)
{
if (*(byte **) target == NULL)
*(byte **) target = mem_alloc (string_size);
if (*(byte **) target)
memcpy (*(byte **) target, buffer, string_size);
else
{
mem_rollback (memtrn);
return (-1);
}
}
buffer += string_size;
break;
case 'm': /* Memory descriptor size */
*((byte *) &dbyte_value) = *(byte *) buffer++;
*((byte *) &dbyte_value + 1) = *(byte *) buffer++;
memory_size = ntohs (dbyte_value);
if (target)
*(dbyte *) target = (dbyte) memory_size;
break;
case 'M': /* Memory descriptor body */
if (target && memory_size > 0)
{
if (*(byte **) target == NULL)
*(byte **) target = mem_alloc ((size_t) memory_size);
if (*(byte **) target)
memcpy (*(byte **) target, buffer,
(size_t) memory_size);
else
{
mem_rollback (memtrn);
return (-1);
}
}
buffer += (size_t) memory_size;
break;
case 'h': /* Huge memory descriptor size */
*((byte *) &qbyte_value) = *(byte *) buffer++;
*((byte *) &qbyte_value + 1) = *(byte *) buffer++;
*((byte *) &qbyte_value + 2) = *(byte *) buffer++;
*((byte *) &qbyte_value + 3) = *(byte *) buffer++;
memory_size = ntohl (qbyte_value);
if (target)
*(qbyte *) target = memory_size;
break;
case 'H': /* Huge memory descriptor body */
if (target && memory_size > 0)
{
if (*(byte **) target == NULL)
*(byte **) target = mem_alloc ((size_t) memory_size);
if (*(byte **) target)
memcpy (*(byte **) target, buffer,
(size_t) memory_size);
else
{
mem_rollback (memtrn);
return (-1);
}
}
buffer += (size_t) memory_size;
break;
}
}
va_end (argptr); /* End variable arguments list */
mem_commit (memtrn);
return (0);
}
/* Function: mem_free_list -- internal
*
* Synopsis: exdr_rollback accepts a list of byte * of a given size. It
* calls mem_free for all non-zero pointrs in that list
*/
void
mem_free_list (byte **ptr_list, dbyte ptr_list_size)
{
while (ptr_list_size--)
{
if (*ptr_list)
mem_free (*ptr_list);
ptr_list++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -