Skip to content
Permalink
Browse files

add RFC103 layer->encoding implementation (#4758)

  • Loading branch information
tbonfort committed Sep 24, 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
@@ -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);
@@ -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);
@@ -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);
@@ -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);
@@ -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;
@@ -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);
@@ -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
@@ -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) */
@@ -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);
@@ -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
}

0 comments on commit 78916c2

Please sign in to comment.
You can’t perform that action at this time.