OSSP CVS Repository

ossp - ossp-pkg/xds/xds_engine_xdr.c 1.1
Not logged in
[Honeypot]  [Browse]  [Directory]  [Home]  [Login
[Reports]  [Search]  [Ticket]  [Timeline
  [Raw

ossp-pkg/xds/xds_engine_xdr.c 1.1
/* 
 * XDS - OSSP Extensible Data Serialization Library Copyright (c) 2001 The
 * OSSP Project (http://www.ossp.org/) Copyright (c) 2001 Cable & Wireless
 * Deutschland (http://www.cw.com/de/)
 * 
 * This file is part of OSSP XDS, an extensible data serialization library
 * which can be found at http://www.ossp.com/pkg/xds/.
 * 
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 
 * EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 * POSSIBILITY OF SUCH DAMAGE. */

#include <string.h>
#include "xds.h"

int xdr_encode_int32(xds_t * xds, void *engine_context,
                     void *buffer, size_t buffer_size,
                     size_t * used_buffer_size, va_list * args)
{
    xds_uint32_t tmp;
    xds_int32_t value;

    xds_init_encoding_engine(4);

    /* Get value and format it into the buffer. */

    value = va_arg(*args, xds_uint32_t);
    if (value < 0) {
        value = 0 - value;
        tmp = 0 - (xds_uint32_t) value;
    }
    else
        tmp = (xds_uint32_t) value;
    ((xds_uint8_t *) buffer)[0] = (tmp >> 24) & 0x000000ff;
    ((xds_uint8_t *) buffer)[1] = (tmp >> 16) & 0x000000ff;
    ((xds_uint8_t *) buffer)[2] = (tmp >> 8) & 0x000000ff;
    ((xds_uint8_t *) buffer)[3] = (tmp >> 0) & 0x000000ff;

    /* Done. */

    return XDS_OK;
}

int xdr_decode_int32(xds_t * xds, void *engine_context,
                     void *buffer, size_t buffer_size,
                     size_t * used_buffer_size, va_list * args)
{
    xds_int32_t *value;
    xds_uint32_t tmp;

    xds_init_decoding_engine(4);

    /* Get value and format it into the buffer. */

    value = va_arg(*args, xds_int32_t *);
    xds_check_parameter(value != NULL);

    if (((xds_uint8_t *) buffer)[0] & 0x80) {   /* negative number */
        tmp = ((xds_uint8_t *) buffer)[0];
        tmp = tmp << 8;
        tmp += ((xds_uint8_t *) buffer)[1];
        tmp = tmp << 8;
        tmp += ((xds_uint8_t *) buffer)[2];
        tmp = tmp << 8;
        tmp += ((xds_uint8_t *) buffer)[3];
        tmp = 0 - tmp;
        *value = 0 - (int32_t) tmp;
    }
    else {                             /* positive number */
        *value = ((xds_uint8_t *) buffer)[0];
        *value = *value << 8;
        *value += ((xds_uint8_t *) buffer)[1];
        *value = *value << 8;
        *value += ((xds_uint8_t *) buffer)[2];
        *value = *value << 8;
        *value += ((xds_uint8_t *) buffer)[3];
    }

    /* Done. */

    return XDS_OK;
}

int xdr_encode_uint32(xds_t * xds, void *engine_context,
                      void *buffer, size_t buffer_size,
                      size_t * used_buffer_size, va_list * args)
{
    xds_uint32_t value;

    xds_init_encoding_engine(4);

    /* Get value and format it into the buffer. */

    value = va_arg(*args, xds_uint32_t);
    ((xds_uint8_t *) buffer)[0] = (value >> 24) & 0x000000ff;
    ((xds_uint8_t *) buffer)[1] = (value >> 16) & 0x000000ff;
    ((xds_uint8_t *) buffer)[2] = (value >> 8) & 0x000000ff;
    ((xds_uint8_t *) buffer)[3] = (value >> 0) & 0x000000ff;

    /* Done. */

    return XDS_OK;
}

int xdr_decode_uint32(xds_t * xds, void *engine_context,
                      void *buffer, size_t buffer_size,
                      size_t * used_buffer_size, va_list * args)
{
    xds_uint32_t *value;

    xds_init_decoding_engine(4);

    /* Get value and format it into the buffer. */

    value = va_arg(*args, xds_uint32_t *);
    xds_check_parameter(value != NULL);

    *value = ((xds_uint8_t *) buffer)[0];
    *value = *value << 8;
    *value += ((xds_uint8_t *) buffer)[1];
    *value = *value << 8;
    *value += ((xds_uint8_t *) buffer)[2];
    *value = *value << 8;
    *value += ((xds_uint8_t *) buffer)[3];

    /* Done. */

    return XDS_OK;
}

#ifdef XDS_HAVE_64_BIT_SUPPORT

int xdr_encode_int64(xds_t * xds, void *engine_context,
                     void *buffer, size_t buffer_size,
                     size_t * used_buffer_size, va_list * args)
{
    xds_uint64_t tmp;
    xds_int64_t value;

    xds_init_encoding_engine(8);

    /* Get value and format it into the buffer. */

    value = va_arg(*args, xds_uint64_t);
    if (value < 0) {
        value = 0 - value;
        tmp = 0 - (xds_uint64_t) value;
    }
    else
        tmp = (xds_uint64_t) value;
    ((xds_uint8_t *) buffer)[0] = (tmp >> 56) & 0x000000ff;
    ((xds_uint8_t *) buffer)[1] = (tmp >> 48) & 0x000000ff;
    ((xds_uint8_t *) buffer)[2] = (tmp >> 40) & 0x000000ff;
    ((xds_uint8_t *) buffer)[3] = (tmp >> 32) & 0x000000ff;
    ((xds_uint8_t *) buffer)[4] = (tmp >> 24) & 0x000000ff;
    ((xds_uint8_t *) buffer)[5] = (tmp >> 16) & 0x000000ff;
    ((xds_uint8_t *) buffer)[6] = (tmp >> 8) & 0x000000ff;
    ((xds_uint8_t *) buffer)[7] = (tmp >> 0) & 0x000000ff;

    /* Done. */

    return XDS_OK;
}

int xdr_decode_int64(xds_t * xds, void *engine_context,
                     void *buffer, size_t buffer_size,
                     size_t * used_buffer_size, va_list * args)
{
    xds_int64_t *value;
    xds_uint64_t tmp;

    xds_init_decoding_engine(8);

    /* Get value and format it into the buffer. */

    value = va_arg(*args, xds_int64_t *);
    xds_check_parameter(value != NULL);

    if (((xds_uint8_t *) buffer)[0] & 0x80) {   /* negative number */
        tmp = ((xds_uint8_t *) buffer)[0];
        tmp = tmp << 8;
        tmp += ((xds_uint8_t *) buffer)[1];
        tmp = tmp << 8;
        tmp += ((xds_uint8_t *) buffer)[2];
        tmp = tmp << 8;
        tmp += ((xds_uint8_t *) buffer)[3];
        tmp = tmp << 8;
        tmp += ((xds_uint8_t *) buffer)[4];
        tmp = tmp << 8;
        tmp += ((xds_uint8_t *) buffer)[5];
        tmp = tmp << 8;
        tmp += ((xds_uint8_t *) buffer)[6];
        tmp = tmp << 8;
        tmp += ((xds_uint8_t *) buffer)[7];
        tmp = 0 - tmp;
        *value = 0 - (xds_int64_t) tmp;
    }
    else {                             /* positive number */
        *value = ((xds_uint8_t *) buffer)[0];
        *value = *value << 8;
        *value += ((xds_uint8_t *) buffer)[1];
        *value = *value << 8;
        *value += ((xds_uint8_t *) buffer)[2];
        *value = *value << 8;
        *value += ((xds_uint8_t *) buffer)[3];
        *value = *value << 8;
        *value += ((xds_uint8_t *) buffer)[4];
        *value = *value << 8;
        *value += ((xds_uint8_t *) buffer)[5];
        *value = *value << 8;
        *value += ((xds_uint8_t *) buffer)[6];
        *value = *value << 8;
        *value += ((xds_uint8_t *) buffer)[7];
    }

    /* Done. */

    return XDS_OK;
}

int xdr_encode_uint64(xds_t * xds, void *engine_context,
                      void *buffer, size_t buffer_size,
                      size_t * used_buffer_size, va_list * args)
{
    xds_uint64_t value;

    xds_init_encoding_engine(8);

    /* Get value and format it into the buffer. */

    value = va_arg(*args, xds_uint64_t);
    ((xds_uint8_t *) buffer)[0] = (value >> 56) & 0x000000ff;
    ((xds_uint8_t *) buffer)[1] = (value >> 48) & 0x000000ff;
    ((xds_uint8_t *) buffer)[2] = (value >> 40) & 0x000000ff;
    ((xds_uint8_t *) buffer)[3] = (value >> 32) & 0x000000ff;
    ((xds_uint8_t *) buffer)[4] = (value >> 24) & 0x000000ff;
    ((xds_uint8_t *) buffer)[5] = (value >> 16) & 0x000000ff;
    ((xds_uint8_t *) buffer)[6] = (value >> 8) & 0x000000ff;
    ((xds_uint8_t *) buffer)[7] = (value >> 0) & 0x000000ff;

    /* Done. */

    return XDS_OK;
}

int xdr_decode_uint64(xds_t * xds, void *engine_context,
                      void *buffer, size_t buffer_size,
                      size_t * used_buffer_size, va_list * args)
{
    xds_uint64_t *value;

    xds_init_decoding_engine(8);

    /* Get value and format it into the buffer. */

    value = va_arg(*args, xds_uint64_t *);
    xds_check_parameter(value != NULL);

    *value = ((xds_uint8_t *) buffer)[0];
    *value = *value << 8;
    *value += ((xds_uint8_t *) buffer)[1];
    *value = *value << 8;
    *value += ((xds_uint8_t *) buffer)[2];
    *value = *value << 8;
    *value += ((xds_uint8_t *) buffer)[3];
    *value = *value << 8;
    *value += ((xds_uint8_t *) buffer)[4];
    *value = *value << 8;
    *value += ((xds_uint8_t *) buffer)[5];
    *value = *value << 8;
    *value += ((xds_uint8_t *) buffer)[6];
    *value = *value << 8;
    *value += ((xds_uint8_t *) buffer)[7];

    /* Done. */

    return XDS_OK;
}

#endif /* XDS_HAVE_64_BIT_SUPPORT */

int xdr_encode_double(xds_t * xds, void *engine_context,
                      void *buffer, size_t buffer_size,
                      size_t * used_buffer_size, va_list * args)
{
    return -1;
}

int xdr_decode_double(xds_t * xds, void *engine_context,
                      void *buffer, size_t buffer_size,
                      size_t * used_buffer_size, va_list * args)
{
    return -1;
}

int xdr_encode_string(xds_t * xds, void *engine_context,
                      void *buffer, size_t buffer_size,
                      size_t * used_buffer_size, va_list * args)
{
    char *p;
    size_t p_len;
    size_t padding;

    xds_init_encoding_engine(4);

    /* Get value from stack and calculate the correct amount of padding. */

    p = va_arg(*args, char *);
    xds_check_parameter(p != NULL);
    p_len = strlen(p);
    padding = (4 - (p_len & 0x03)) & 0x03;
    assert((p_len + padding) % 4 == 0);

    /* We need (4 + p_len + padding) bytes in the buffer to format our
     * parameter. If we don't have them, return an underflow error. */

    *used_buffer_size = 4 + p_len + padding;
    if (buffer_size < *used_buffer_size)
        return XDS_ERR_OVERFLOW;

    /* Format the values into the buffer. */

    ((xds_uint8_t *) buffer)[0] = (p_len >> 24) & 0x000000ff;
    ((xds_uint8_t *) buffer)[1] = (p_len >> 16) & 0x000000ff;
    ((xds_uint8_t *) buffer)[2] = (p_len >> 8) & 0x000000ff;
    ((xds_uint8_t *) buffer)[3] = (p_len >> 0) & 0x000000ff;
    memmove((xds_uint8_t *) buffer + 4, p, p_len);
    memset((xds_uint8_t *) buffer + 4 + p_len, 0, padding);

    /* Done. */

    return XDS_OK;
}

int xdr_decode_string(xds_t * xds, void *engine_context,
                      void *buffer, size_t buffer_size,
                      size_t * used_buffer_size, va_list * args)
{
    char **p;
    size_t p_len;
    size_t padding;

    xds_init_decoding_engine(4);

    p = va_arg(*args, char **);
    xds_check_parameter(p != NULL);

    /* Read the size of the message. */

    p_len = ((xds_uint8_t *) buffer)[0];
    p_len = p_len << 8;
    p_len += ((xds_uint8_t *) buffer)[1];
    p_len = p_len << 8;
    p_len += ((xds_uint8_t *) buffer)[2];
    p_len = p_len << 8;
    p_len += ((xds_uint8_t *) buffer)[3];

    /* Calculate padding. */

    padding = (4 - (p_len & 0x03)) & 0x03;

    /* Do we have enough data?. */

    *used_buffer_size = 4 + p_len + padding;
    if (buffer_size < *used_buffer_size)
        return XDS_ERR_UNDERFLOW;

    /* Allocate buffer for the data. */

    *p = (char *)malloc(p_len + 1);
    if (*p == NULL)
        return XDS_ERR_NO_MEM;

    /* Copy data into the buffer. */

    memmove(*p, (xds_uint8_t *) buffer + 4, p_len);
    ((xds_uint8_t *) buffer)[4 + p_len] = '\0';

    /* Done. */

    return XDS_OK;
}

int xdr_encode_octetstream(xds_t * xds, void *engine_context,
                           void *buffer, size_t buffer_size,
                           size_t * used_buffer_size, va_list * args)
{
    xds_uint8_t *p;
    size_t p_len;
    size_t padding;

    xds_init_encoding_engine(4);

    /* Get value from stack and calculate the correct amount of padding. */

    p = (xds_uint8_t *) va_arg(*args, void *);
    xds_check_parameter(p != NULL);
    p_len = va_arg(*args, size_t);
    padding = (4 - (p_len & 0x03)) & 0x03;
    assert((p_len + padding) % 4 == 0);

    /* We need (4 + p_len + padding) bytes in the buffer to format our
     * parameter. If we don't have them, return an underflow error. */

    *used_buffer_size = 4 + p_len + padding;
    if (buffer_size < *used_buffer_size)
        return XDS_ERR_OVERFLOW;

    /* Format the values into the buffer. */

    ((xds_uint8_t *) buffer)[0] = (p_len >> 24) & 0x000000ff;
    ((xds_uint8_t *) buffer)[1] = (p_len >> 16) & 0x000000ff;
    ((xds_uint8_t *) buffer)[2] = (p_len >> 8) & 0x000000ff;
    ((xds_uint8_t *) buffer)[3] = (p_len >> 0) & 0x000000ff;
    memmove((xds_uint8_t *) buffer + 4, p, p_len);
    memset((xds_uint8_t *) buffer + 4 + p_len, 0, padding);

    /* Done. */

    return XDS_OK;
}

int xdr_decode_octetstream(xds_t * xds, void *engine_context,
                           void *buffer, size_t buffer_size,
                           size_t * used_buffer_size, va_list * args)
{
    void **p;
    size_t *p_len;
    size_t padding;

    xds_init_decoding_engine(4);

    p = va_arg(*args, void **);
    p_len = va_arg(*args, size_t *);
    xds_check_parameter(p != NULL);
    xds_check_parameter(p_len != NULL);

    /* Read the size of the message. */

    *p_len = ((xds_uint8_t *) buffer)[0];
    *p_len = *p_len << 8;
    *p_len += ((xds_uint8_t *) buffer)[1];
    *p_len = *p_len << 8;
    *p_len += ((xds_uint8_t *) buffer)[2];
    *p_len = *p_len << 8;
    *p_len += ((xds_uint8_t *) buffer)[3];

    /* Calculate padding. */

    padding = (4 - (*p_len & 0x03)) & 0x03;

    /* Do we have enough data?. */

    *used_buffer_size = 4 + *p_len + padding;
    if (buffer_size < *used_buffer_size)
        return XDS_ERR_UNDERFLOW;

    /* Allocate buffer for the data. */

    *p = malloc(*p_len);
    if (*p == NULL)
        return XDS_ERR_NO_MEM;

    /* Copy data into the buffer. */

    memmove(*p, (xds_uint8_t *) buffer + 4, *p_len);

    /* Done. */

    return XDS_OK;
}

CVSTrac 2.0.1