Permalink
Browse files

add RFC103 layer->encoding implementation (#4758)

  • Loading branch information...
tbonfort committed Aug 29, 2013
1 parent 5e30781 commit 78916c298add3d5505f423c1484e1680d7abb137
Showing with 172 additions and 337 deletions.
  1. +1 −4 mapcontext.c
  2. +1 −0 mapcopy.c
  3. +7 −0 mapfile.c
  4. +1 −3 mapgml.c
  5. +20 −0 maplayer.c
  6. +6 −21 mapogcsos.c
  7. +0 −15 mapowscommon.c
  8. +0 −3 mapowscommon.h
  9. +4 −1 mapserver.h
  10. +56 −0 mapstring.c
  11. +7 −26 mapwcs.c
  12. +20 −59 mapwcs11.c
  13. +4 −15 mapwcs20.c
  14. +8 −34 mapwfs.c
  15. +12 −37 mapwfs11.c
  16. +24 −118 mapwms.c
  17. +1 −1 msautotest
View
@@ -1333,10 +1333,7 @@ int msWriteMapContext(mapObj *map, FILE *stream)
}
/* file header */
- msOWSPrintEncodeMetadata(stream, &(map->web.metadata),
- NULL, "wms_encoding", OWS_NOERR,
- "<?xml version='1.0' encoding=\"%s\" standalone=\"no\" ?>\n",
- "ISO-8859-1");
+ msIO_fprintf( stream, "<?xml version='1.0' encoding=\"UTF-8\" standalone=\"no\" ?>\n");
/* set the WMS_Viewer_Context information */
pszEncodedVal = msEncodeHTMLEntities(version);
View
@@ -934,6 +934,7 @@ int msCopyLayer(layerObj *dst, layerObj *src)
MS_COPYSTRING(dst->name, src->name);
MS_COPYSTRING(dst->group, src->group);
MS_COPYSTRING(dst->data, src->data);
+ MS_COPYSTRING(dst->encoding, src->encoding);
MS_COPYSTELEM(status);
MS_COPYSTELEM(type);
View
@@ -3918,6 +3918,8 @@ int initLayer(layerObj *layer, mapObj *map)
initExpression(&(layer->_geomtransform));
layer->_geomtransform.type = MS_GEOMTRANSFORM_NONE;
+ layer->encoding = NULL;
+
return(0);
}
@@ -3958,6 +3960,7 @@ int freeLayer(layerObj *layer)
msLayerClose(layer);
msFree(layer->name);
+ msFree(layer->encoding);
msFree(layer->group);
msFree(layer->data);
msFree(layer->classitem);
@@ -4236,6 +4239,9 @@ int loadLayer(layerObj *layer, mapObj *map)
msSetError(MS_EOFERR, NULL, "loadLayer()");
return(-1);
break;
+ case(ENCODING):
+ if(getString(&layer->encoding) == MS_FAILURE) return(-1);
+ break;
case(END):
if(layer->type == -1) {
msSetError(MS_MISCERR, "Layer type not set.", "loadLayer()");
@@ -4638,6 +4644,7 @@ static void writeLayer(FILE *stream, int indent, layerObj *layer)
writeKeyword(stream, indent, "CONNECTIONTYPE", layer->connectiontype, 10, MS_SDE, "SDE", MS_OGR, "OGR", MS_POSTGIS, "POSTGIS", MS_WMS, "WMS", MS_ORACLESPATIAL, "ORACLESPATIAL", MS_WFS, "WFS", MS_PLUGIN, "PLUGIN", MS_UNION, "UNION", MS_UVRASTER, "UVRASTER", MS_CONTOUR, "CONTOUR");
writeString(stream, indent, "DATA", NULL, layer->data);
writeNumber(stream, indent, "DEBUG", 0, layer->debug); /* is this right? see loadLayer() */
+ writeString(stream, indent, "ENCODING", NULL, layer->encoding);
writeExtent(stream, indent, "EXTENT", layer->extent);
writeExpression(stream, indent, "FILTER", &(layer->filter));
writeString(stream, indent, "FILTERITEM", NULL, layer->filteritem);
View
@@ -1151,9 +1151,7 @@ int msGMLWriteQuery(mapObj *map, char *filename, const char *namespaces)
}
}
- /* charset encoding: lookup "gml_encoding" metadata first, then */
- /* "wms_encoding", and if not found then use "ISO-8859-1" as default. */
- msOWSPrintEncodeMetadata(stream, &(map->web.metadata), namespaces, "encoding", OWS_NOERR, "<?xml version=\"1.0\" encoding=\"%s\"?>\n\n", "ISO-8859-1");
+ msIO_fprintf(stream, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n");
msOWSPrintValidateMetadata(stream, &(map->web.metadata), namespaces, "rootname", OWS_NOERR, "<%s ", "msGMLOutput");
msOWSPrintEncodeMetadata(stream, &(map->web.metadata), namespaces, "uri", OWS_NOERR, "xmlns=\"%s\"", NULL);
View
@@ -279,10 +279,20 @@ int msLayerNextShape(layerObj *layer, shapeObj *shape)
/* We need to leverage the iteminfo (I think) at this point */
rv = layer->vtable->LayerNextShape(layer, shape);
+ if(rv != MS_SUCCESS)
+ return rv;
/* RFC89 Apply Layer GeomTransform */
if(layer->_geomtransform.type != MS_GEOMTRANSFORM_NONE && rv == MS_SUCCESS) {
rv = msGeomTransformShape(layer->map, layer, shape);
+ if(rv != MS_SUCCESS)
+ return rv;
+ }
+
+ if(layer->encoding) {
+ rv = msLayerEncodeShapeAttributes(layer,shape);
+ if(rv != MS_SUCCESS)
+ return rv;
}
return rv;
@@ -323,10 +333,20 @@ int msLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record)
*/
rv = layer->vtable->LayerGetShape(layer, shape, record);
+ if(rv != MS_SUCCESS)
+ return rv;
/* RFC89 Apply Layer GeomTransform */
if(layer->_geomtransform.type != MS_GEOMTRANSFORM_NONE && rv == MS_SUCCESS) {
rv = msGeomTransformShape(layer->map, layer, shape);
+ if(rv != MS_SUCCESS)
+ return rv;
+ }
+
+ if(layer->encoding) {
+ rv = msLayerEncodeShapeAttributes(layer,shape);
+ if(rv != MS_SUCCESS)
+ return rv;
}
return rv;
View
@@ -82,7 +82,6 @@ static int msSOSException(mapObj *map, char *locator, char *exceptionCode)
char *errorString = NULL;
char *errorMessage = NULL;
char *schemasLocation = NULL;
- const char *encoding;
xmlDocPtr psDoc = NULL;
xmlNodePtr psRootNode = NULL;
@@ -91,7 +90,6 @@ static int msSOSException(mapObj *map, char *locator, char *exceptionCode)
psNsOws = xmlNewNs(NULL, BAD_CAST "http://www.opengis.net/ows/1.1", BAD_CAST "ows");
- encoding = msOWSLookupMetadata(&(map->web.metadata), "SO", "encoding");
errorString = msGetErrorString("\n");
errorMessage = msEncodeHTMLEntities(errorString);
schemasLocation = msEncodeHTMLEntities(msOWSGetSchemasLocation(map));
@@ -104,13 +102,10 @@ static int msSOSException(mapObj *map, char *locator, char *exceptionCode)
xmlNewNs(psRootNode, BAD_CAST "http://www.opengis.net/ows/1.1", BAD_CAST "ows");
- if (encoding)
- msIO_setHeader("Content-Type","text/xml; charset=%s", encoding);
- else
- msIO_setHeader("Content-Type","text/xml");
+ msIO_setHeader("Content-Type","text/xml; charset=UTF-8");
msIO_sendHeaders();
- xmlDocDumpFormatMemoryEnc(psDoc, &buffer, &size, (encoding ? encoding : "ISO-8859-1"), 1);
+ xmlDocDumpFormatMemoryEnc(psDoc, &buffer, &size, ("UTF-8"), 1);
msIO_printf("%s", buffer);
@@ -1109,7 +1104,6 @@ int msSOSGetCapabilities(mapObj *map, sosParamsObj *sosparams, cgiRequestObj *re
char *xsi_schemaLocation = NULL;
char *script_url=NULL;
const char *updatesequence=NULL;
- const char *encoding;
int i,j,k;
layerObj *lp = NULL, *lpTmp = NULL;
@@ -1185,7 +1179,6 @@ int msSOSGetCapabilities(mapObj *map, sosParamsObj *sosparams, cgiRequestObj *re
/* updateSequence */
updatesequence = msOWSLookupMetadata(&(map->web.metadata), "SO", "updatesequence");
- encoding = msOWSLookupMetadata(&(map->web.metadata), "SO", "encoding");
if (sosparams->pszUpdateSequence != NULL) {
i = msOWSNegotiateUpdateSequence(sosparams->pszUpdateSequence, updatesequence);
@@ -1605,10 +1598,7 @@ int msSOSGetCapabilities(mapObj *map, sosParamsObj *sosparams, cgiRequestObj *re
if ( msIO_needBinaryStdout() == MS_FAILURE )
return MS_FAILURE;
- if (encoding)
- msIO_setHeader("Content-Type","text/xml; charset=%s", encoding);
- else
- msIO_setHeader("Content-Type","text/xml");
+ msIO_setHeader("Content-Type","text/xml; charset=UTF-8");
msIO_sendHeaders();
/*TODO* : check the encoding validity. Internally libxml2 uses UTF-8
@@ -1624,7 +1614,7 @@ int msSOSGetCapabilities(mapObj *map, sosParamsObj *sosparams, cgiRequestObj *re
context = msIO_getHandler(stdout);
- xmlDocDumpFormatMemoryEnc(psDoc, &buffer, &size, (encoding ? encoding : "ISO-8859-1"), 1);
+ xmlDocDumpFormatMemoryEnc(psDoc, &buffer, &size, ("UTF-8"), 1);
msIO_contextWrite(context, buffer, size);
xmlFree(buffer);
@@ -1718,7 +1708,6 @@ int msSOSGetObservation(mapObj *map, sosParamsObj *sosparams, cgiRequestObj *req
xmlNodePtr psObservationNode = NULL, psResultNode=NULL;
const char *pszProcedure = NULL;
const char *pszBlockSep=NULL;
- const char *encoding;
char *pszResult=NULL;
int nDiffrentProc = 0;
SOSProcedureNode *paDiffrentProc = NULL;
@@ -1731,7 +1720,6 @@ int msSOSGetObservation(mapObj *map, sosParamsObj *sosparams, cgiRequestObj *req
/* establish local namespace */
pszTmp = msOWSLookupMetadata(&(map->web.metadata), "SFO", "namespace_uri");
- encoding = msOWSLookupMetadata(&(map->web.metadata), "SO", "encoding");
if(pszTmp) user_namespace_uri = pszTmp;
@@ -2458,14 +2446,11 @@ this request. Check sos/ows_enable_request settings.", "msSOSGetObservation()",
}
/* output results */
- if (encoding)
- msIO_setHeader("Content-Type","text/xml; charset=%s", encoding);
- else
- msIO_setHeader("Content-Type","text/xml");
+ msIO_setHeader("Content-Type","text/xml; charset=UTF-8");
msIO_sendHeaders();
context = msIO_getHandler(stdout);
- xmlDocDumpFormatMemoryEnc(psDoc, &buffer, &size, (encoding ? encoding : "ISO-8859-1"), 1);
+ xmlDocDumpFormatMemoryEnc(psDoc, &buffer, &size, ("UTF-8"), 1);
msIO_contextWrite(context, buffer, size);
free(schemalocation);
free(xsi_schemaLocation);
View
@@ -615,21 +615,6 @@ int _validateNamespace(xmlNsPtr psNsOws)
return MS_FAILURE;
}
-xmlNodePtr msOWSCommonxmlNewChildEncoded( xmlNodePtr psParent, xmlNsPtr psNs, const char* name,
- const char *content, const char *encoding)
-{
- char *encoded = NULL;
- xmlNodePtr psNode;
-
- if (encoding && content) {
- encoded = msGetEncodedString(content, encoding);
- psNode = xmlNewChild(psParent, psNs, BAD_CAST name, BAD_CAST encoded);
- msFree(encoded);
- return psNode;
- } else
- return xmlNewChild(psParent, psNs, BAD_CAST name, BAD_CAST content);
-}
-
/*
* Valid an xml string against an XML schema
* Inpired from: http://xml.developpez.com/sources/?page=validation#validate_XSD_CppCLI_2
View
@@ -116,9 +116,6 @@ xmlNodePtr msOWSCommonWGS84BoundingBox(xmlNsPtr psNsOws, int dimensions, double
int _validateNamespace(xmlNsPtr psNsOws);
-xmlNodePtr msOWSCommonxmlNewChildEncoded( xmlNodePtr psParent, xmlNsPtr psNs, const char* name,
- const char *content, const char *encoding);
-
int msOWSSchemaValidation(const char* xml_schema, const char* xml);
#endif /* defined(USE_LIBXML2) */
View
@@ -1658,7 +1658,9 @@ extern "C" {
#ifndef SWIG
expressionObj _geomtransform;
-#endif
+#endif
+
+ char *encoding; /* for iconving shape attributes. ignored if NULL or "utf-8" */
};
@@ -2312,6 +2314,7 @@ void msPopulateTextSymbolForLabelAndString(textSymbolObj *ts, labelObj *l, char
MS_DLL_EXPORT char *msLayerGetProcessingKey( layerObj *layer, const char *);
MS_DLL_EXPORT int msLayerClearProcessing( layerObj *layer );
MS_DLL_EXPORT char* msLayerGetFilterString( layerObj *layer );
+ MS_DLL_EXPORT int msLayerEncodeShapeAttributes( layerObj *layer, shapeObj *shape);
MS_DLL_EXPORT int msLayerSupportsCommonFilters(layerObj *layer);
MS_DLL_EXPORT int msTokenizeExpression(expressionObj *expression, char **list, int *listsize);
View
@@ -2074,3 +2074,59 @@ int msStringInArray( const char * pszString, char **array, int numelements)
}
return MS_FALSE;
}
+
+int msLayerEncodeShapeAttributes( layerObj *layer, shapeObj *shape) {
+
+#ifdef USE_ICONV
+ iconv_t cd = NULL;
+ const char *inp;
+ char *outp, *out = NULL;
+ size_t len, bufsize, bufleft, iconv_status;
+ int i;
+#endif
+
+ if( !layer->encoding || !*layer->encoding || !strcasecmp(layer->encoding, "UTF-8"))
+ return MS_SUCCESS;
+
+ cd = iconv_open("UTF-8", layer->encoding);
+ if(cd == (iconv_t)-1) {
+ msSetError(MS_IDENTERR, "Encoding not supported by libiconv (%s).",
+ "msGetEncodedString()", layer->encoding);
+ return MS_FAILURE;
+ }
+
+#ifdef USE_ICONV
+ for(i=0;i <shape->numvalues; i++) {
+ if(!shape->values[i] || (len = strlen(shape->values[i]))==0) {
+ continue; /* Nothing to do */
+ }
+
+ bufsize = len * 6 + 1; /* Each UTF-8 char can be up to 6 bytes */
+ inp = shape->values[i];
+ out = (char*) msSmallMalloc(bufsize);
+
+ strlcpy(out, shape->values[i], bufsize);
+ outp = out;
+
+ bufleft = bufsize;
+ iconv_status = -1;
+
+ while (len > 0) {
+ iconv_status = iconv(cd, (char**)&inp, &len, &outp, &bufleft);
+ if(iconv_status == -1) {
+ msFree(out);
+ continue; /* silently ignore failed conversions */
+ }
+ }
+ out[bufsize - bufleft] = '\0';
+ msFree(shape->values[i]);
+ shape->values[i] = out;
+ }
+ iconv_close(cd);
+
+ return MS_SUCCESS;
+#else
+ msSetError(MS_MISCERR, "Not implemented since Iconv is not enabled.", "msGetEncodedString()");
+ return MS_FAILURE;
+#endif
+}
Oops, something went wrong.

0 comments on commit 78916c2

Please sign in to comment.