Ticket #467: shp2pgsql_iconv_error_policy.patch

File shp2pgsql_iconv_error_policy.patch, 4.7 KB (added by agnat, 2 years ago)
  • loader/shp2pgsql-core.c

     
    4040 * Internal functions 
    4141 */ 
    4242 
    43 char *utf8(const char *fromcode, char *inputbuf); 
     43char *utf8(const SHPLOADERCONFIG *config, char *inputbuf); 
    4444void vasbappend(stringbuffer_t *sb, char *fmt, ... ); 
    4545char *escape_copy_string(char *str); 
    4646char *escape_insert_string(char *str); 
     
    7777 
    7878/* Return allocated string containing UTF8 string converted from encoding fromcode */ 
    7979char * 
    80 utf8(const char *fromcode, char *inputbuf) 
     80utf8(const SHPLOADERCONFIG *config, char *inputbuf) 
    8181{ 
    8282        iconv_t cd; 
    8383        char *outputptr; 
     
    8787 
    8888        inbytesleft = strlen(inputbuf); 
    8989 
    90         cd = iconv_open("UTF-8", fromcode); 
     90        cd = iconv_open(config->target_encoding, config->encoding); 
    9191        if ( cd == ((iconv_t)(-1)) ) 
    9292                return NULL; 
    9393 
     
    856856        config->createindex = 0; 
    857857        config->readshape = 1; 
    858858        config->encoding = strdup(ENCODING_DEFAULT); 
     859        config->target_encoding = strdup(ICONV_POLICY_ERROR); 
    859860        config->null_policy = POLICY_NULL_INSERT; 
    860861        config->sr_id = -1; 
    861862        config->hwgeom = 0; 
     
    11481149                if (state->config->encoding) 
    11491150                { 
    11501151                        /* If we are converting from another encoding to UTF8, convert the field name to UTF8 */ 
    1151                         utf8str = utf8(state->config->encoding, name); 
     1152                        utf8str = utf8(state->config, name); 
    11521153                        if (!utf8str) 
    11531154                        { 
    11541155                                snprintf(state->message, SHPLOADERMSGLEN, "Unable to convert field name \"%s\" to UTF-8: iconv reports \"%s\"", name, strerror(errno)); 
     
    15751576                        if (state->config->encoding) 
    15761577                        { 
    15771578                                /* If we are converting from another encoding to UTF8, convert the field value to UTF8 */ 
    1578                                 utf8str = utf8(state->config->encoding, val); 
     1579                                utf8str = utf8(state->config, val); 
    15791580                                if (!utf8str) 
    15801581                                { 
    15811582                                        snprintf(state->message, SHPLOADERMSGLEN, "Unable to convert field value \"%s\" to UTF-8: iconv reports \"%s\"", val, strerror(errno)); 
  • loader/shp2pgsql-core.h

     
    4040 
    4141 
    4242/* 
     43 * Error policies for iconv 
     44 */ 
     45 
     46#define ICONV_POLICY_ERROR      "UTF-8" 
     47#define ICONV_POLICY_IGNORE     "UTF-8//IGNORE" 
     48#define ICONV_POLICY_TRANSLIT   "UTF-8//TRANSLIT" 
     49 
     50/* 
    4351 * Error message handling 
    4452 */ 
    4553 
     
    7179#define ENCODING_DEFAULT "WINDOWS-1252" 
    7280 
    7381/* 
    74  * Structure to hold the loader configuration options  
     82 * Structure to hold the loader configuration options 
    7583 */ 
    7684 
    7785typedef struct shp_loader_config 
     
    8694        char *schema; 
    8795 
    8896        /* geometry column name to use */ 
    89         char *geom;  
     97        char *geom; 
    9098 
    9199        /* the shape file (without the .shp extension) */ 
    92100        char *shp_file; 
     
    96104 
    97105        /* 0 = MULTIPOLYGON/MULTILINESTRING, 1 = force to POLYGON/LINESTRING */ 
    98106        int simple_geometries; 
    99          
     107 
    100108        /* 0 = geometry, 1 = geography */ 
    101109        int geography; 
    102110 
     
    115123        /* iconv encoding name */ 
    116124        char *encoding; 
    117125 
     126        /* always UTF-8 but with different iconv error policies */ 
     127        char *target_encoding; 
     128 
    118129        /* how to handle nulls */ 
    119130        int null_policy; 
    120131 
     
    128139 
    129140 
    130141/* 
    131  * Structure to holder the current loader state  
     142 * Structure to holder the current loader state 
    132143 */ 
    133144 
    134145typedef struct shp_loader_state 
     
    138149 
    139150        /* Shapefile handle */ 
    140151        SHPHandle hSHPHandle; 
    141          
     152 
    142153        /* Shapefile type */ 
    143154        int shpfiletype; 
    144155 
  • loader/shp2pgsql-cli.c

     
    4141        printf("  -S  Generate simple geometries instead of MULTI geometries.\n"); 
    4242        printf("  -W <encoding> Specify the character encoding of Shape's\n"); 
    4343        printf("     attribute column. (default : \"WINDOWS-1252\")\n"); 
     44        printf("  -C (e|i|t) Character encoding error policy.\n"); 
     45        printf("     (e: error, i: ignore, t: transliterate, default: error)\n"); 
    4446        printf("  -N <policy> NULL geometries handling policy (insert*,skip,abort)\n"); 
    4547        printf("  -n  Only import DBF file.\n"); 
    4648        printf("  -?  Display this help screen.\n"); 
     
    132134                        config->encoding = optarg; 
    133135                        break; 
    134136 
     137                case 'C': 
     138                        switch (optarg[0]) 
     139                        { 
     140                        case 'e': 
     141                                config->target_encoding = ICONV_POLICY_ERROR; 
     142                                break; 
     143 
     144                        case 'i': 
     145                                config->target_encoding = ICONV_POLICY_IGNORE; 
     146                                break; 
     147 
     148                        case 't': 
     149                                config->target_encoding = ICONV_POLICY_TRANSLIT; 
     150                                break; 
     151 
     152                        default: 
     153                                fprintf(stderr, "Unsupported character encoding error policy.\nValid options: error, ignore, transliterate\n"); 
     154                                exit(1); 
     155                        } 
     156                        break; 
    135157                case 'N': 
    136158                        switch (optarg[0]) 
    137159                        {