1
1
/**********************************************************************
2
* $Id: shp2pgsql-core.c 5195 2010-02-03 22:42:13Z pramsey $
2
* $Id: shp2pgsql-core.c 5989 2010-09-19 16:54:59Z mcayland $
4
4
* PostGIS - Spatial Types for PostgreSQL
5
5
* http://postgis.refractions.net
43
char *utf8(const char *fromcode, char *inputbuf);
44
void vasbappend(stringbuffer_t *sb, char *fmt, ... );
40
* Internal return values
43
#define UTF8_GOOD_RESULT 0
44
#define UTF8_BAD_RESULT 1
45
#define UTF8_NO_RESULT 2
48
* Only turn this on if you want to skip bad UTF8 charaters. Not a good
49
* idea, generally, as "bad characters" usually indicate that the source
50
* encoding is *not* UTF8
52
#define UTF8_DROP_BAD_CHARACTERS 0
55
int utf8(const char *fromcode, char *inputbuf, char **outputbuf);
45
56
char *escape_copy_string(char *str);
46
57
char *escape_insert_string(char *str);
90
99
cd = iconv_open("UTF-8", fromcode);
91
100
if ( cd == ((iconv_t)(-1)) )
101
return UTF8_NO_RESULT;
94
103
outbytesleft = inbytesleft * 3 + 1; /* UTF8 string can be 3 times larger */
95
/* then local string */
96
outputbuf = (char *)malloc(outbytesleft);
100
memset(outputbuf, 0, outbytesleft);
101
outputptr = outputbuf;
103
if (-1 == iconv(cd, &inputbuf, &inbytesleft, &outputptr, &outbytesleft))
105
*outputbuf = (char *)malloc(outbytesleft);
107
return UTF8_NO_RESULT;
109
/* Clean out the buffer */
110
memset(*outputbuf, 0, outbytesleft);
111
outputptr = *outputbuf;
113
/* Does this string convert cleanly? */
114
if ( iconv(cd, &inputbuf, &inbytesleft, &outputptr, &outbytesleft) == -1 )
118
/* No. Try to convert it while transliterating. */
119
iconvctl(cd, ICONV_SET_TRANSLITERATE, &on);
120
if ( iconv(cd, &inputbuf, &inbytesleft, &outputptr, &outbytesleft) == -1 )
122
/* No. Try to convert it while discarding errors. */
123
iconvctl(cd, ICONV_SET_DISCARD_ILSEQ, &on);
124
if ( iconv(cd, &inputbuf, &inbytesleft, &outputptr, &outbytesleft) == -1 )
126
/* Still no. Throw away the buffer and return. */
129
return UTF8_NO_RESULT;
133
return UTF8_BAD_RESULT;
137
return UTF8_NO_RESULT;
140
/* Return a good result, converted string is in buffer. */
142
return UTF8_GOOD_RESULT;
254
* Escape strings that are to be used as part of a PostgreSQL connection string. If no
255
* characters require escaping, simply return the input pointer. Otherwise return a
256
* new allocated string.
259
escape_connection_string(char *str)
262
* Escape apostrophes and backslashes:
266
* 1. find # of characters
277
/* Count how many characters we need to escape so we know the size of the string we need to return */
280
if (*ptr == '\'' || *ptr == '\\')
286
/* If we don't have to escape anything, simply return the input pointer */
290
size = ptr - str + toescape + 1;
291
result = calloc(1, size);
297
if (*ptr == '\'' || *ptr == '\\')
220
310
* @brief Generate an allocated geometry string for shapefile object obj using the state parameters
406
496
if (state->config->simple_geometries == 0)
408
498
lwcollection = lwcollection_construct(MULTILINETYPE, state->config->sr_id, NULL, obj->nParts, lwmultilinestrings);
500
/* When outputting wkt rather than wkb, we need to remove the SRID from the inner geometries */
501
if (state->config->hwgeom)
503
for (u = 0; u < obj->nParts; u++)
504
lwmultilinestrings[u]->SRID = -1;
409
507
serialized_lwgeom = lwgeom_serialize(lwcollection_as_lwgeom(lwcollection));
762
860
if (state->config->simple_geometries == 0)
764
862
lwcollection = lwcollection_construct(MULTIPOLYGONTYPE, state->config->sr_id, NULL, polygon_total, lwpolygons);
864
/* When outputting wkt rather than wkb, we need to remove the SRID from the inner geometries */
865
if (state->config->hwgeom)
867
for (u = 0; u < pi; u++)
868
lwpolygons[u]->SRID = -1;
765
871
serialized_lwgeom = lwgeom_serialize(lwcollection_as_lwgeom(lwcollection));
1148
1258
if (state->config->encoding)
1150
/* If we are converting from another encoding to UTF8, convert the field name to UTF8 */
1151
utf8str = utf8(state->config->encoding, name);
1260
static char *encoding_msg = "Try \"LATIN1\" (Western European), or one of the values described at http://www.postgresql.org/docs/current/static/multibyte.html.";
1262
int rv = utf8(state->config->encoding, name, &utf8str);
1264
if (rv != UTF8_GOOD_RESULT)
1154
snprintf(state->message, SHPLOADERMSGLEN, "Unable to convert field name \"%s\" to UTF-8: iconv reports \"%s\"", name, strerror(errno));
1266
if( rv == UTF8_BAD_RESULT )
1267
snprintf(state->message, SHPLOADERMSGLEN, "Unable to convert field name \"%s\" to UTF-8 (iconv reports \"%s\"). Current encoding is \"%s\". %s", utf8str, strerror(errno), state->config->encoding, encoding_msg);
1268
else if( rv == UTF8_NO_RESULT )
1269
snprintf(state->message, SHPLOADERMSGLEN, "Unable to convert field name to UTF-8 (iconv reports \"%s\"). Current encoding is \"%s\". %s", strerror(errno), state->config->encoding, encoding_msg);
1271
snprintf(state->message, SHPLOADERMSGLEN, "Unexpected return value from utf8()");
1273
if( rv == UTF8_BAD_RESULT )
1155
1276
return SHPLOADERERR;
1575
1696
if (state->config->encoding)
1698
static char *encoding_msg = "Try \"LATIN1\" (Western European), or one of the values described at http://www.postgresql.org/docs/current/static/multibyte.html.";
1577
1699
/* If we are converting from another encoding to UTF8, convert the field value to UTF8 */
1578
utf8str = utf8(state->config->encoding, val);
1581
snprintf(state->message, SHPLOADERMSGLEN, "Unable to convert field value \"%s\" to UTF-8: iconv reports \"%s\"", val, strerror(errno));
1582
return SHPLOADERERR;
1585
strncpy(val, utf8str, MAXVALUELEN);
1700
int rv = utf8(state->config->encoding, val, &utf8str);
1701
if ( !UTF8_DROP_BAD_CHARACTERS && rv != UTF8_GOOD_RESULT )
1703
if( rv == UTF8_BAD_RESULT )
1704
snprintf(state->message, SHPLOADERMSGLEN, "Unable to convert data value \"%s\" to UTF-8 (iconv reports \"%s\"). Current encoding is \"%s\". %s", utf8str, strerror(errno), state->config->encoding, encoding_msg);
1705
else if( rv == UTF8_NO_RESULT )
1706
snprintf(state->message, SHPLOADERMSGLEN, "Unable to convert data value to UTF-8 (iconv reports \"%s\"). Current encoding is \"%s\". %s", strerror(errno), state->config->encoding, encoding_msg);
1708
snprintf(state->message, SHPLOADERMSGLEN, "Unexpected return value from utf8()");
1710
if( rv == UTF8_BAD_RESULT )
1713
return SHPLOADERERR;
1715
/* Optionally (compile-time) suppress bad UTF8 values */
1716
if ( UTF8_DROP_BAD_CHARACTERS && rv != UTF8_GOOD_RESULT )
1723
/* The utf8str buffer is only alloc'ed if the UTF8 conversion works */
1724
if ( rv == UTF8_GOOD_RESULT )
1726
strncpy(val, utf8str, MAXVALUELEN);
1589
1731
/* Escape attribute correctly according to dump format */
1690
1832
return SHPLOADERERR;
1695
/* Now generate the geometry string according to the current configuration */
1696
if (state->config->hwgeom)
1698
/* Old-style hwgeom (WKT) */
1699
if (!state->config->dump_format)
1700
vasbappend(sb, "GeomFromText('");
1836
/* Now generate the geometry string according to the current configuration */
1837
if (state->config->hwgeom)
1839
/* Old-style hwgeom (WKT) */
1840
if (!state->config->dump_format)
1841
vasbappend(sb, "GeomFromText('");
1844
/* Output SRID if relevant */
1845
if (state->config->sr_id != 0)
1846
vasbappend(sb, "SRID=%d;", state->config->sr_id);
1849
vasbappend(sb, "%s", geometry);
1851
if (!state->config->dump_format)
1853
vasbappend(sb, "'");
1855
/* Output SRID if relevant */
1856
if (state->config->sr_id != 0)
1857
vasbappend(sb, ", %d)", state->config->sr_id);
1859
vasbappend(sb, ")");
1703
/* Output SRID if relevant */
1704
if (state->config->sr_id != 0)
1705
vasbappend(sb, "SRID=%d;", state->config->sr_id);
1708
vasbappend(sb, "%s", geometry);
1710
if (!state->config->dump_format)
1712
vasbappend(sb, "'");
1714
/* Output SRID if relevant */
1715
if (state->config->sr_id != 0)
1716
vasbappend(sb, ", %d)", state->config->sr_id);
1718
vasbappend(sb, ")");
1723
/* New style lwgeom (HEXEWKB) */
1724
if (!state->config->dump_format)
1725
vasbappend(sb, "'");
1727
vasbappend(sb, "%s", geometry);
1729
if (!state->config->dump_format)
1730
vasbappend(sb, "'");
1864
/* New style lwgeom (HEXEWKB) */
1865
if (!state->config->dump_format)
1866
vasbappend(sb, "'");
1868
vasbappend(sb, "%s", geometry);
1870
if (!state->config->dump_format)
1871
vasbappend(sb, "'");
1733
1877
/* Tidy up everything */
1734
1878
SHPDestroyObject(obj);
1738
1881
/* Close the line correctly for dump/insert format */