Skip to content

Commit

Permalink
add RFC103 layer->encoding implementation (#4758)
Browse files Browse the repository at this point in the history
  • Loading branch information
tbonfort committed Sep 24, 2013
1 parent 5e30781 commit 78916c2
Show file tree
Hide file tree
Showing 17 changed files with 172 additions and 337 deletions.
5 changes: 1 addition & 4 deletions mapcontext.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions mapcopy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions mapfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -3918,6 +3918,8 @@ int initLayer(layerObj *layer, mapObj *map)
initExpression(&(layer->_geomtransform));
layer->_geomtransform.type = MS_GEOMTRANSFORM_NONE;

layer->encoding = NULL;

return(0);
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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()");
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 1 addition & 3 deletions mapgml.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
20 changes: 20 additions & 0 deletions maplayer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
27 changes: 6 additions & 21 deletions mapogcsos.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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));
Expand All @@ -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);

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand All @@ -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);

Expand Down Expand Up @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -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);
Expand Down
15 changes: 0 additions & 15 deletions mapowscommon.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 0 additions & 3 deletions mapowscommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) */
Expand Down
5 changes: 4 additions & 1 deletion mapserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -1658,7 +1658,9 @@ extern "C" {

#ifndef SWIG
expressionObj _geomtransform;
#endif
#endif

char *encoding; /* for iconving shape attributes. ignored if NULL or "utf-8" */
};


Expand Down Expand Up @@ -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);
Expand Down
56 changes: 56 additions & 0 deletions mapstring.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Loading

0 comments on commit 78916c2

Please sign in to comment.