postgresql/src/interfaces/ecpg/pgtypeslib/common.c

149 lines
3.1 KiB
C
Raw Normal View History

2010-09-20 22:08:53 +02:00
/* src/interfaces/ecpg/pgtypeslib/common.c */
2006-07-30 12:24:10 +02:00
#include "postgres_fe.h"
2003-03-20 16:56:50 +01:00
#include "pgtypes.h"
#include "pgtypeslib_extern.h"
/* Return value is zero-filled. */
2003-03-20 16:56:50 +01:00
char *
pgtypes_alloc(long size)
{
2003-08-04 02:43:34 +02:00
char *new = (char *) calloc(1L, size);
2003-03-20 16:56:50 +01:00
if (!new)
errno = ENOMEM;
return new;
2003-03-20 16:56:50 +01:00
}
char *
pgtypes_strdup(const char *str)
2003-03-20 16:56:50 +01:00
{
2003-08-04 02:43:34 +02:00
char *new = (char *) strdup(str);
2003-03-20 16:56:50 +01:00
if (!new)
errno = ENOMEM;
return new;
2003-03-20 16:56:50 +01:00
}
int
2003-08-04 02:43:34 +02:00
pgtypes_fmt_replace(union un_fmt_comb replace_val, int replace_type, char **output, int *pstr_len)
{
/*
* general purpose variable, set to 0 in order to fix compiler warning
*/
int i = 0;
switch (replace_type)
{
case PGTYPES_TYPE_NOTHING:
break;
case PGTYPES_TYPE_STRING_CONSTANT:
case PGTYPES_TYPE_STRING_MALLOCED:
i = strlen(replace_val.str_val);
2003-08-04 02:43:34 +02:00
if (i + 1 <= *pstr_len)
{
/* include trailing terminator in what we copy */
memcpy(*output, replace_val.str_val, i + 1);
*pstr_len -= i;
*output += i;
2003-08-04 02:43:34 +02:00
if (replace_type == PGTYPES_TYPE_STRING_MALLOCED)
free(replace_val.str_val);
return 0;
}
2003-08-04 02:43:34 +02:00
else
return -1;
break;
case PGTYPES_TYPE_CHAR:
2003-08-04 02:43:34 +02:00
if (*pstr_len >= 2)
{
(*output)[0] = replace_val.char_val;
(*output)[1] = '\0';
(*pstr_len)--;
(*output)++;
return 0;
}
2003-08-04 02:43:34 +02:00
else
return -1;
break;
case PGTYPES_TYPE_DOUBLE_NF:
case PGTYPES_TYPE_INT64:
case PGTYPES_TYPE_UINT:
case PGTYPES_TYPE_UINT_2_LZ:
case PGTYPES_TYPE_UINT_2_LS:
case PGTYPES_TYPE_UINT_3_LZ:
case PGTYPES_TYPE_UINT_4_LZ:
{
2003-08-04 02:43:34 +02:00
char *t = pgtypes_alloc(PGTYPES_FMT_NUM_MAX_DIGITS);
if (!t)
return ENOMEM;
2003-08-04 02:43:34 +02:00
switch (replace_type)
{
case PGTYPES_TYPE_DOUBLE_NF:
i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
2003-08-04 02:43:34 +02:00
"%0.0g", replace_val.double_val);
break;
case PGTYPES_TYPE_INT64:
i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
2003-08-04 02:43:34 +02:00
INT64_FORMAT, replace_val.int64_val);
break;
case PGTYPES_TYPE_UINT:
2003-08-04 02:43:34 +02:00
i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
"%u", replace_val.uint_val);
break;
case PGTYPES_TYPE_UINT_2_LZ:
2003-08-04 02:43:34 +02:00
i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
"%02u", replace_val.uint_val);
break;
case PGTYPES_TYPE_UINT_2_LS:
2003-08-04 02:43:34 +02:00
i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
"%2u", replace_val.uint_val);
break;
case PGTYPES_TYPE_UINT_3_LZ:
2003-08-04 02:43:34 +02:00
i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
"%03u", replace_val.uint_val);
break;
case PGTYPES_TYPE_UINT_4_LZ:
2003-08-04 02:43:34 +02:00
i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
"%04u", replace_val.uint_val);
break;
}
2018-08-15 22:29:31 +02:00
if (i < 0 || i >= PGTYPES_FMT_NUM_MAX_DIGITS)
2003-08-04 02:43:34 +02:00
{
free(t);
return -1;
}
i = strlen(t);
*pstr_len -= i;
2003-08-04 02:43:34 +02:00
/*
* if *pstr_len == 0, we don't have enough space for the
* terminator and the conversion fails
*/
if (*pstr_len <= 0)
{
free(t);
return -1;
}
strcpy(*output, t);
*output += i;
free(t);
}
break;
default:
break;
}
return 0;
}
/* Functions declared in pgtypes.h. */
/* Just frees memory (mostly needed for Windows) */
void
PGTYPESchar_free(char *ptr)
{
free(ptr);
}