Header And Logo

PostgreSQL
| The world's most advanced open source database.

common.c

Go to the documentation of this file.
00001 /* src/interfaces/ecpg/pgtypeslib/common.c */
00002 
00003 #include "postgres_fe.h"
00004 
00005 #include "extern.h"
00006 
00007 /* Return value is zero-filled. */
00008 char *
00009 pgtypes_alloc(long size)
00010 {
00011     char       *new = (char *) calloc(1L, size);
00012 
00013     if (!new)
00014         errno = ENOMEM;
00015     return (new);
00016 }
00017 
00018 char *
00019 pgtypes_strdup(const char *str)
00020 {
00021     char       *new = (char *) strdup(str);
00022 
00023     if (!new)
00024         errno = ENOMEM;
00025     return (new);
00026 }
00027 
00028 int
00029 pgtypes_fmt_replace(union un_fmt_comb replace_val, int replace_type, char **output, int *pstr_len)
00030 {
00031     /*
00032      * general purpose variable, set to 0 in order to fix compiler warning
00033      */
00034     int         i = 0;
00035 
00036     switch (replace_type)
00037     {
00038         case PGTYPES_TYPE_NOTHING:
00039             break;
00040         case PGTYPES_TYPE_STRING_CONSTANT:
00041         case PGTYPES_TYPE_STRING_MALLOCED:
00042             i = strlen(replace_val.str_val);
00043             if (i + 1 <= *pstr_len)
00044             {
00045                 /*
00046                  * copy over i + 1 bytes, that includes the tailing terminator
00047                  */
00048                 strncpy(*output, replace_val.str_val, i + 1);
00049                 *pstr_len -= i;
00050                 *output += i;
00051                 if (replace_type == PGTYPES_TYPE_STRING_MALLOCED)
00052                     free(replace_val.str_val);
00053                 return 0;
00054             }
00055             else
00056                 return -1;
00057             break;
00058         case PGTYPES_TYPE_CHAR:
00059             if (*pstr_len >= 2)
00060             {
00061                 (*output)[0] = replace_val.char_val;
00062                 (*output)[1] = '\0';
00063                 (*pstr_len)--;
00064                 (*output)++;
00065                 return 0;
00066             }
00067             else
00068                 return -1;
00069             break;
00070         case PGTYPES_TYPE_DOUBLE_NF:
00071         case PGTYPES_TYPE_INT64:
00072         case PGTYPES_TYPE_UINT:
00073         case PGTYPES_TYPE_UINT_2_LZ:
00074         case PGTYPES_TYPE_UINT_2_LS:
00075         case PGTYPES_TYPE_UINT_3_LZ:
00076         case PGTYPES_TYPE_UINT_4_LZ:
00077             {
00078                 char       *t = pgtypes_alloc(PGTYPES_FMT_NUM_MAX_DIGITS);
00079 
00080                 if (!t)
00081                     return ENOMEM;
00082                 switch (replace_type)
00083                 {
00084                     case PGTYPES_TYPE_DOUBLE_NF:
00085                         i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
00086                                      "%0.0g", replace_val.double_val);
00087                         break;
00088                     case PGTYPES_TYPE_INT64:
00089                         i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
00090                                      INT64_FORMAT, replace_val.int64_val);
00091                         break;
00092                     case PGTYPES_TYPE_UINT:
00093                         i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
00094                                      "%u", replace_val.uint_val);
00095                         break;
00096                     case PGTYPES_TYPE_UINT_2_LZ:
00097                         i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
00098                                      "%02u", replace_val.uint_val);
00099                         break;
00100                     case PGTYPES_TYPE_UINT_2_LS:
00101                         i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
00102                                      "%2u", replace_val.uint_val);
00103                         break;
00104                     case PGTYPES_TYPE_UINT_3_LZ:
00105                         i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
00106                                      "%03u", replace_val.uint_val);
00107                         break;
00108                     case PGTYPES_TYPE_UINT_4_LZ:
00109                         i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
00110                                      "%04u", replace_val.uint_val);
00111                         break;
00112                 }
00113 
00114                 if (i < 0)
00115                 {
00116                     free(t);
00117                     return -1;
00118                 }
00119                 i = strlen(t);
00120                 *pstr_len -= i;
00121 
00122                 /*
00123                  * if *pstr_len == 0, we don't have enough space for the
00124                  * terminator and the conversion fails
00125                  */
00126                 if (*pstr_len <= 0)
00127                 {
00128                     free(t);
00129                     return -1;
00130                 }
00131                 strcpy(*output, t);
00132                 *output += i;
00133                 free(t);
00134             }
00135             break;
00136         default:
00137             break;
00138     }
00139     return 0;
00140 }