| iMatix home page
| << | < | > | >>
SFL Logo SFL
Version 2.11

 

exdr_read

#include "sflexdr.h"
int
exdr_read (const byte *buffer, const char *format, ...)

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);

Source Code - (sflexdr.c)

{
    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);
}

| << | < | > | >> iMatix Copyright © 1996-2000 iMatix Corporation