⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sflexdr.c

📁 短小精悍的C语言标准函数库。提供450个以上的可移植的算法和工具代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
            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 + -