Age Owner TLA Line data Source code
1 : /* src/interfaces/ecpg/pgtypeslib/common.c */
2 :
3 : #include "postgres_fe.h"
4 :
5 : #include "pgtypes.h"
6 : #include "pgtypeslib_extern.h"
7 :
8 : /* Return value is zero-filled. */
9 : char *
7325 meskes 10 CBC 36765 : pgtypes_alloc(long size)
11 : {
7188 bruce 12 36765 : char *new = (char *) calloc(1L, size);
13 :
7325 meskes 14 36765 : if (!new)
7325 meskes 15 UBC 0 : errno = ENOMEM;
2061 peter_e 16 CBC 36765 : return new;
17 : }
18 :
19 : char *
4130 meskes 20 389 : pgtypes_strdup(const char *str)
21 : {
7188 bruce 22 389 : char *new = (char *) strdup(str);
23 :
7325 meskes 24 389 : if (!new)
7325 meskes 25 UBC 0 : errno = ENOMEM;
2061 peter_e 26 CBC 389 : return new;
27 : }
28 :
29 : int
7188 bruce 30 19 : pgtypes_fmt_replace(union un_fmt_comb replace_val, int replace_type, char **output, int *pstr_len)
31 : {
32 : /*
33 : * general purpose variable, set to 0 in order to fix compiler warning
34 : */
35 19 : int i = 0;
36 :
37 19 : switch (replace_type)
38 : {
7191 meskes 39 2 : case PGTYPES_TYPE_NOTHING:
7313 40 2 : break;
7191 41 4 : case PGTYPES_TYPE_STRING_CONSTANT:
42 : case PGTYPES_TYPE_STRING_MALLOCED:
43 4 : i = strlen(replace_val.str_val);
7188 bruce 44 4 : if (i + 1 <= *pstr_len)
45 : {
46 : /* include trailing terminator in what we copy */
1758 tgl 47 4 : memcpy(*output, replace_val.str_val, i + 1);
7313 meskes 48 4 : *pstr_len -= i;
49 4 : *output += i;
7188 bruce 50 4 : if (replace_type == PGTYPES_TYPE_STRING_MALLOCED)
7191 meskes 51 UBC 0 : free(replace_val.str_val);
7313 meskes 52 CBC 4 : return 0;
53 : }
54 : else
7188 bruce 55 UBC 0 : return -1;
56 : break;
7191 meskes 57 CBC 1 : case PGTYPES_TYPE_CHAR:
7188 bruce 58 1 : if (*pstr_len >= 2)
59 : {
7191 meskes 60 1 : (*output)[0] = replace_val.char_val;
7313 61 1 : (*output)[1] = '\0';
62 1 : (*pstr_len)--;
63 1 : (*output)++;
64 1 : return 0;
65 : }
66 : else
7188 bruce 67 UBC 0 : return -1;
68 : break;
7191 meskes 69 CBC 12 : case PGTYPES_TYPE_DOUBLE_NF:
70 : case PGTYPES_TYPE_INT64:
71 : case PGTYPES_TYPE_UINT:
72 : case PGTYPES_TYPE_UINT_2_LZ:
73 : case PGTYPES_TYPE_UINT_2_LS:
74 : case PGTYPES_TYPE_UINT_3_LZ:
75 : case PGTYPES_TYPE_UINT_4_LZ:
76 : {
7188 bruce 77 12 : char *t = pgtypes_alloc(PGTYPES_FMT_NUM_MAX_DIGITS);
78 :
79 12 : if (!t)
7313 meskes 80 UBC 0 : return ENOMEM;
81 : switch (replace_type)
82 : {
7191 83 0 : case PGTYPES_TYPE_DOUBLE_NF:
7313 84 0 : i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
85 : "%0.0g", replace_val.double_val);
86 0 : break;
7191 87 0 : case PGTYPES_TYPE_INT64:
7313 88 0 : i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
89 : INT64_FORMAT, replace_val.int64_val);
90 0 : break;
7191 meskes 91 CBC 3 : case PGTYPES_TYPE_UINT:
7188 bruce 92 3 : i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
93 : "%u", replace_val.uint_val);
7313 meskes 94 3 : break;
7191 95 8 : case PGTYPES_TYPE_UINT_2_LZ:
7188 bruce 96 8 : i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
97 : "%02u", replace_val.uint_val);
7313 meskes 98 8 : break;
7191 meskes 99 UBC 0 : case PGTYPES_TYPE_UINT_2_LS:
7188 bruce 100 0 : i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
101 : "%2u", replace_val.uint_val);
7313 meskes 102 0 : break;
7191 meskes 103 CBC 1 : case PGTYPES_TYPE_UINT_3_LZ:
7188 bruce 104 1 : i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
105 : "%03u", replace_val.uint_val);
7313 meskes 106 1 : break;
7191 meskes 107 UBC 0 : case PGTYPES_TYPE_UINT_4_LZ:
7188 bruce 108 0 : i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
109 : "%04u", replace_val.uint_val);
7313 meskes 110 0 : break;
111 : }
112 :
1698 tgl 113 CBC 12 : if (i < 0 || i >= PGTYPES_FMT_NUM_MAX_DIGITS)
114 : {
7313 meskes 115 UBC 0 : free(t);
116 0 : return -1;
117 : }
7313 meskes 118 CBC 12 : i = strlen(t);
119 12 : *pstr_len -= i;
120 :
121 : /*
122 : * if *pstr_len == 0, we don't have enough space for the
123 : * terminator and the conversion fails
124 : */
7188 bruce 125 12 : if (*pstr_len <= 0)
126 : {
7313 meskes 127 UBC 0 : free(t);
128 0 : return -1;
129 : }
7313 meskes 130 CBC 12 : strcpy(*output, t);
131 12 : *output += i;
132 12 : free(t);
133 : }
134 12 : break;
7313 meskes 135 UBC 0 : default:
136 0 : break;
137 : }
7313 meskes 138 CBC 14 : return 0;
139 : }
140 :
141 : /* Functions declared in pgtypes.h. */
142 :
143 : /* Just frees memory (mostly needed for Windows) */
144 : void
1756 tmunro 145 1189 : PGTYPESchar_free(char *ptr)
146 : {
147 1189 : free(ptr);
148 1189 : }
|