/*
**    Name: store.c
**
**    Date: Thu Jan 17 12:02:13 2002
**
*/

#include "ODBC.h"
#include "rmamem.h"
#include "sqlext.h"
#include "sql.h"
#include <string.h>

/* Store one parameter, copying references into RMA for the DM task */

void store_parameter(int parameter,ODBCLibParameterType type,int size)
    {
    ODBCLibParameter *p;

    int len;

    char *copy;

    if (odbcparameter_index >= ODBCLIBMAXPARAMETERS)
        {
        request_error(&odbcerror_parameters);
        return;
        }

    p = &odbcquerytype.parameters[odbcparameter_index];

    odbcparameter_copyback[odbcparameter_index] = 0;
    odbcparameter_index++;

    p->type  = type;
    p->size  = size;
    p->value = parameter;

    if (type != ODBC_REFERENCE)
        {
        if (type != ODBC_VALUE)
            {
            p->type = ODBC_VALUE;
            }
        return;
        }

    if (size > 0 && parameter > 0)
        {
        len = size;
        }
    else if (size == SQL_NTS && parameter > 0)
        {
        len = strlen((char *)parameter) + 1;
        }
    else
        {
        if (size <= 0)
            {
            p->type = ODBC_VALUE;
            }
        return;
        }

    copy = rmamalloc(len);

    if (copy == NULL)
        {
        p->type  = ODBC_VALUE;
        p->value = 0;
        request_error(&odbcerror_memory);
        return;
        }

    memcpy(copy,(void *)parameter,len);

    p->value = (int)copy;

    if (size > 0)
        {
        odbcparameter_copyback[odbcparameter_index - 1] = len;
        }
    }

/* Store an output buffer whose length the driver may ignore */

void store_output_parameter(int parameter,int size)
    {
    ODBCLibParameter *p;

    char *copy;

    int index;

    int alloc;

    switch (size)
        {
        case SQL_IS_POINTER:
        case SQL_IS_UINTEGER:
        case SQL_IS_INTEGER:
            size = 4;
            break;

        case SQL_IS_USMALLINT:
        case SQL_IS_SMALLINT:
            size = 2;
            break;
        }

    if (parameter <= 0)
        {
        store_parameter(parameter,ODBC_VALUE,0);
        return;
        }

    index = odbcparameter_index;

    store_parameter(0,ODBC_VALUE,0);

    if (odbcparameter_index != index + 1)
        {
        return;
        }

    p = &odbcquerytype.parameters[index];

    alloc = size > ODBC_SCRATCH_SIZE ? size : ODBC_SCRATCH_SIZE;

    copy = rmamalloc(alloc);

    if (copy == NULL)
        {
        request_error(&odbcerror_memory);
        return;
        }

    memset(copy,0,alloc);

    if (size > 0)
        {
        memcpy(copy,(void *)parameter,size);
        odbcparameter_copyback[index] = size;
        }

    p->type  = ODBC_REFERENCE;
    p->size  = size;
    p->value = (int)copy;
    }
