[Mapserver-dev] speeding up mapserver
Mladen Turk
mturk at apache.org
Tue Jun 1 14:35:08 EDT 2004
This is a multi-part message in MIME format.
------=_NextPart_000_0059_01C44817.DA87D840
Content-Type: text/plain;
charset="US-ASCII"
Content-Transfer-Encoding: 7bit
Hi all,
Perhaps someone will find me too boring, but what the heck...
I would like to propose two things.
a) make the loadForm functionality 'public'
b) make the loadForm 'smarter'
The loadForm from mapserv/mapserv_fastcgi is a quite useful function usable
from more then simple CGI app, cause it is a simple param/value parser after
all.
Inside the docs, there is a statement that the map file is case insensitive,
but when looking in the source I found a whole bunch of 'strcasecmp' that
for each char makes a function call to 'tolower'. If the configuration
parameters 'are' case insensitive, then IMHO making them lowercase on the
'input' stream (either file or request) would make case sensitive comparator
unneeded.
Also, having a fixed set of comparable strings makes me thinking...
Here is my proposal.
I someone heard of 'gperf', then IMO for larger subset of comparable string
params something like this can be used:
gperf -L ANSI-C -S 1 -s 3 -t -T -D -k '1-126,$' -l <mapparserx.g
>mapparserx.c
with mapparserx.g
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "maptemplate.h"
#include "mapparserx.h"
%}
struct mapParseKeywords {
const char *name;
int id;
int type;
};
%%
"service", MSP_SERVICE, MST_SERV
"queryfile", MSP_QUERYFILE, MST_FORM
"savequery", MSP_SAVEQUERY, MST_FORM
"zoom", MSP_ZOOM, MST_FORM
"zoomdir", MSP_ZOOMDIR, MST_FORM
"zoomsize", MSP_ZOOMSIZE, MST_FORM
"imgext", MSP_IMGEXT, MST_FORM
"searchmap", MSP_SEARCHMAP, MST_FORM
"mapext", MSP_MAPEXT, MST_FORM
"minx", MSP_MINX, MST_FORM
"maxx", MSP_MAXX, MST_FORM
"miny", MSP_MINY, MST_FORM
"maxy", MSP_MAXY, MST_FORM
"mapxy", MSP_MAPXY, MST_FORM
"mapshape", MSP_MAPSHAPE, MST_FORM
"img.x", MSP_IMG_X, MST_FORM
"img.y", MSP_IMG_Y, MST_FORM
"imgxy", MSP_IMGXY, MST_FORM
"imgbox", MSP_IMGBOX, MST_FORM
"imgshape", MSP_IMGSHAPE, MST_FORM
"ref.x", MSP_REF_X, MST_FORM
"ref.y", MSP_REF_Y, MST_FORM
"refxy", MSP_REFXY, MST_FORM
"buffer", MSP_BUFFER, MST_FORM
"imgsize", MSP_IMGSIZE, MST_FORM
"mapsize", MSP_MAPSIZE, MST_FORM
"layers", MSP_LAYERS, MST_FORM
"layer", MSP_LAYER, MST_FORM
"qlayer", MSP_QLAYER, MST_FORM
"qitem", MSP_QITEM, MST_FORM
"qstring", MSP_QSTRING, MST_FORM
"slayer", MSP_SLAYER, MST_FORM
"shapeindex", MSP_SHAPEINDEX, MST_FORM
"tileindex", MSP_TILEINDEX, MST_FORM
"mode", MSP_MODE, MST_FORM
"id", MSP_ID, MST_FORM
"scale", MSP_SCALE, MST_FORM
"browse", BROWSE, MST_MODE
"zoomin", ZOOMIN, MST_MODE
"zoomout", ZOOMOUT, MST_MODE
"map", MAP, MST_MODE
"legend", LEGEND, MST_MODE
"reference", REFERENCE, MST_MODE
"scalebar", SCALEBAR, MST_MODE
"coordinate", COORDINATE, MST_MODE
"query", QUERY, MST_MODE
"querymap", QUERYMAP, MST_MODE
"nquery", NQUERY, MST_MODE
"nquerymap", NQUERYMAP, MST_MODE
"itemquery", ITEMQUERY, MST_MODE
"itemquerymap", ITEMQUERYMAP, MST_MODE
"itemnquery", ITEMNQUERY, MST_MODE
"itemnquerymap", ITEMNQUERYMAP, MST_MODE
"featurequery", FEATUREQUERY, MST_MODE
"featurequerymap", FEATUREQUERYMAP, MST_MODE
"featurenquery", FEATURENQUERY, MST_MODE
"featurenquerymap", FEATURENQUERYMAP, MST_MODE
"itemfeaturequery", ITEMFEATUREQUERY, MST_MODE
"itemfeaturequerymap", ITEMFEATUREQUERYMAP, MST_MODE
"itemfeaturenquery", ITEMFEATURENQUERY, MST_MODE
"itemfeaturenquerymap", ITEMFEATURENQUERYMAP, MST_MODE
"indexquery", INDEXQUERY, MST_MODE
"indexquerymap", INDEXQUERYMAP, MST_MODE
And mapparserx.h
#ifndef MAPPARSERX_H
#define MAPPARSERX_H
/*
** Keyword definitions for the mapdefines (used by gperf)
*/
typedef struct mapParseKeywords mapParseKeywords;
struct mapParseKeywords {
const char *name;
int id;
int type;
};
struct mapParseKeywords *in_word_set (const char *str,
unsigned int len);
#define MST_FORM 1
#define MST_MODE 2
#define MST_SERV 3
#define MSP_QUERYFILE 101
#define MSP_SAVEQUERY 102
#define MSP_ZOOM 103
#define MSP_ZOOMDIR 104
#define MSP_ZOOMSIZE 105
#define MSP_IMGEXT 106
#define MSP_SEARCHMAP 107
#define MSP_MAPEXT 108
#define MSP_MINX 109
#define MSP_MAXX 110
#define MSP_MINY 111
#define MSP_MAXY 112
#define MSP_MAPXY 113
#define MSP_MAPSHAPE 114
#define MSP_IMG_X 115
#define MSP_IMG_Y 116
#define MSP_IMGXY 117
#define MSP_IMGBOX 118
#define MSP_IMGSHAPE 119
#define MSP_REF_X 120
#define MSP_REF_Y 121
#define MSP_REFXY 122
#define MSP_BUFFER 123
#define MSP_IMGSIZE 124
#define MSP_MAPSIZE 125
#define MSP_LAYERS 126
#define MSP_LAYER 127
#define MSP_QLAYER 128
#define MSP_QITEM 129
#define MSP_QSTRING 130
#define MSP_SLAYER 131
#define MSP_SHAPEINDEX 132
#define MSP_TILEINDEX 133
#define MSP_MODE 134
#define MSP_ID 135
#define MSP_SCALE 136
/* TODO: WMS Server params */
#define MSP_SERVICE 137
#define MSP_VERSION 138
#define MSP_WMTVER 139
#define MSP_REQUEST 140
#define MSP_EXCEPTIONS 141
#define MSP_FORMAT 142
/* TODO: WFS Server params */
#define MSP_MAXFEATURES 143
#define MSP_BBOX 144
#define MSP_TYPENAME 145
#define MSP_FILTER 146
#define MSP_OUTPUTFORMAT 147
#endif /* MAPPARSERX_H */
So, it will produce the 'almost' perfect hash for each param.
Here is my snapshot of the rewritten loadForm:
static double atofx(const char *str, int *err)
{
char b[64];
char *p, *c, *s;
double r;
s = &b[0];
strncpy(s, str, 62);
s[63] = '\0';
p = strrchr(s, '.');
c = strrchr(s, ',');
if (p && c) {
if (p < c) {
/* remove all points */
rmallch(s, '.');
for (p = s; *p; p++) {
if (*p == ',')
*p = '.';
}
}
else
rmallch(s, ',');
}
else if (c && !p) {
if (strchr(s, ',') == c)
s[c-s] = '.';
rmallch(s, ',');
}
else if (p && !c) {
if (strchr(s, '.') != c)
rmallch(s, '.');
}
r = strtod(s, &p);
if (err && *p)
*err = -1;
return r;
}
static double satof(const char *str)
{
return atofx(str, NULL);
}
static int atoix(const char *str, int *err)
{
char *p;
long l;
l = strtol(str, &p, 10);
if (err && *p)
*err = -1;
return (int)l;
}
static char *strncpyx(char *dst, const char *src, size_t n)
{
char *d = dst;
--n;
if (n > 0) {
const char *s = src;
do {
if ((*d++ = *s++) == 0) {
/* NUL pad the remaining n-1 bytes */
while (--n != 0)
*d++ = 0;
break;
}
} while (--n != 0);
}
*d = 0;
return (dst);
}
int msLoadMapParam(mapObj *map, const char *name,
const char *value, int loadCustom)
{
int j, k;
char tmpstr[1024];
if (strncmp(name, "map_", 4) == 0) {
if (msLoadMapString(map, (char *)name, (char *)value) == -1) {
return -1;
}
}
if (!loadCustom)
return 0;
if (_snprintf(tmpstr, sizeof(tmpstr) - 1, "%%%s%%", name) < 1) {
return -1;
}
for (j = 0; j < map->numlayers; j++) {
if (map->layers[j].data && (strstr(map->layers[j].data, tmpstr) !=
NULL))
map->layers[j].data = gsub(map->layers[j].data, tmpstr, value);
if (map->layers[j].connection && (strstr(map->layers[j].connection,
tmpstr) != NULL))
map->layers[j].connection = gsub(map->layers[j].connection,
tmpstr, value);
if (map->layers[j].filter.string &&
(strstr(map->layers[j].filter.string, tmpstr) != NULL))
map->layers[j].filter.string =
gsub(map->layers[j].filter.string, tmpstr, value);
for (k = 0; k < map->layers[j].numclasses; k++) {
if ( map->layers[j].class[k].expression.string &&
(strstr(map->layers[j].class[k].expression.string, tmpstr) != NULL))
map->layers[j].class[k].expression.string =
gsub(map->layers[j].class[k].expression.string, tmpstr, value);
}
}
return 0;
}
#define CONVERSION_ERROR(x) \
do { \
if (x != 0) { \
msSetError(MS_WEBERR, "Parameter number conversion.", "loadForm()");
\
return -1; \
} } while (0)
int msLoadFormParam(mapservObj *msObj,
const char *name, const char *value)
{
int j, n, cve = 0;
char **tokens = NULL;
struct mapParseKeywords *kwd;
kwd = in_word_set(name, strlen(name));
if (!kwd || kwd->type != MST_FORM) {
msSetError(MS_WEBERR, "Unreckognized keyword.", "loadForm()");
return -1;
}
switch (kwd->id) {
case MSP_QUERYFILE:
if (msObj->QueryFile)
free(msObj->QueryFile);
msObj->QueryFile = strdup(value);
break;
case MSP_SAVEQUERY:
msObj->SaveQuery = MS_TRUE;
break;
case MSP_ZOOM:
msObj->Zoom = atofx(value, &cve);
CONVERSION_ERROR(cve);
if ((msObj->Zoom > MAXZOOM) || (msObj->Zoom < MINZOOM)) {
msSetError(MS_WEBERR, "Zoom value out of range.", "loadForm()");
return -1;
}
break;
case MSP_ZOOMDIR:
msObj->ZoomDirection = atoix(value, &cve);
CONVERSION_ERROR(cve);
if((msObj->ZoomDirection != -1) && (msObj->ZoomDirection != 1) &&
(msObj->ZoomDirection != 0)) {
msSetError(MS_WEBERR, "Zoom direction must be 1, 0 or -1.",
"loadForm()");
return -1;
}
break;
case MSP_ZOOMSIZE: // absolute zoom magnitude
msObj->ZoomSize = atoix(value, &cve);
CONVERSION_ERROR(cve);
if ((msObj->ZoomSize > MAXZOOM) || (msObj->ZoomSize < 1)) {
msSetError(MS_WEBERR, "Invalid zoom size.", "loadForm()");
return -1;
}
break;
case MSP_IMGEXT: // extent of an existing image in a web application
tokens = split(value, ' ', &n);
if (!tokens || n != 4) {
msSetError(MS_WEBERR, "Not enough arguments for imgext.",
"loadForm()");
return -1;
}
msObj->ImgExt.minx = atofx(tokens[0], &cve);
msObj->ImgExt.miny = atofx(tokens[1], &cve);
msObj->ImgExt.maxx = atofx(tokens[2], &cve);
msObj->ImgExt.maxy = atofx(tokens[3], &cve);
msFreeCharArray(tokens, 4);
CONVERSION_ERROR(cve);
break;
case MSP_SEARCHMAP:
msObj->SearchMap = MS_TRUE;
break;
case MSP_ID:
strncpyx(msObj->Id, value, IDSIZE);
break;
case MSP_MAPEXT: // extent of the new map or query
if (strncasecmp(value, "shape", 5) == 0)
msObj->UseShapes = MS_TRUE;
else {
tokens = split(value, ' ', &n);
if(!tokens) {
msSetError(MS_MEMERR, NULL, "loadForm()");
return -1;
}
if(n != 4) {
msSetError(MS_WEBERR, "Not enough arguments for mapext.",
"loadForm()");
return -1;
}
msObj->Map->extent.minx = atofx(tokens[0], &cve);
msObj->Map->extent.miny = atofx(tokens[1], &cve);
msObj->Map->extent.maxx = atofx(tokens[2], &cve);
msObj->Map->extent.maxy = atofx(tokens[3], &cve);
msFreeCharArray(tokens, 4);
CONVERSION_ERROR(cve);
#ifdef USE_PROJ
// make sure both coordinates are in range!
if (msObj->Map->projection.proj &&
!pj_is_latlong(msObj->Map->projection.proj)
&& (msObj->Map->extent.minx >= -180.0 &&
msObj->Map->extent.minx <= 180.0)
&& (msObj->Map->extent.miny >= -90.0 &&
msObj->Map->extent.miny <= 90.0)
&& (msObj->Map->extent.maxx >= -180.0 &&
msObj->Map->extent.maxx <= 180.0)
&& (msObj->Map->extent.maxy >= -90.0 &&
msObj->Map->extent.maxy <= 90.0))
msProjectRect(&(msObj->Map->latlon),
&(msObj->Map->projection),
&(msObj->Map->extent)); // extent is a in lat/lon
#endif
if ((msObj->Map->extent.minx != msObj->Map->extent.maxx) &&
(msObj->Map->extent.miny != msObj->Map->extent.maxy)) { //
extent seems ok
msObj->CoordSource = FROMUSERBOX;
msObj->QueryCoordSource = FROMUSERBOX;
}
}
break;
case MSP_MINX: // extent of the new map, in pieces
msObj->Map->extent.minx = atofx(value, &cve);
CONVERSION_ERROR(cve);
break;
case MSP_MAXX:
msObj->Map->extent.maxx = atofx(value, &cve);
CONVERSION_ERROR(cve);
break;
case MSP_MINY:
msObj->Map->extent.miny = atofx(value, &cve);
CONVERSION_ERROR(cve);
break;
case MSP_MAXY:
msObj->Map->extent.maxy = atofx(value, &cve);
CONVERSION_ERROR(cve);
msObj->CoordSource = FROMUSERBOX;
msObj->QueryCoordSource = FROMUSERBOX;
break;
case MSP_MAPXY: // user map coordinate
if (strncasecmp(value, "shape", 5) == 0) {
msObj->UseShapes = MS_TRUE;
}
else {
tokens = split(value, ' ', &n);
if(!tokens || n != 2) {
msSetError(MS_WEBERR, "Not enough arguments for mapxy.",
"loadForm()");
return -1;
}
msObj->MapPnt.x = atofx(tokens[0], &cve);
msObj->MapPnt.y = atofx(tokens[1], &cve);
msFreeCharArray(tokens, 2);
CONVERSION_ERROR(cve);
#ifdef USE_PROJ
if (msObj->Map->projection.proj &&
!pj_is_latlong(msObj->Map->projection.proj)
&& (msObj->MapPnt.x >= -180.0 && msObj->MapPnt.x <= 180.0)
&& (msObj->MapPnt.y >= -90.0 && msObj->MapPnt.y <= 90.0))
msProjectPoint(&(msObj->Map->projection),
&(msObj->Map->projection),
&msObj->MapPnt); // point is a in lat/lon
#endif
if (msObj->CoordSource == NONE) { // don't override previous
settings (i.e. buffer or scale )
msObj->CoordSource = FROMUSERPNT;
msObj->QueryCoordSource = FROMUSERPNT;
}
}
break;
case MSP_MAPSHAPE: // query shape
{
lineObj line = {0, NULL};
tokens = split(value, ' ', &n);
if ((line.point = (pointObj *)malloc(sizeof(pointObj)*(n/2))) ==
NULL) {
msSetError(MS_MEMERR, NULL, "loadForm()");
return -1;
}
line.numpoints = n/2;
msInitShape(&(msObj->SelectShape));
msObj->SelectShape.type = MS_SHAPE_POLYGON;
for (j = 0; j < n/2; j++) {
line.point[j].x = atof(tokens[2 * j]);
line.point[j].y = atof(tokens[2 * j + 1]);
#ifdef USE_PROJ
if (msObj->Map->projection.proj &&
!pj_is_latlong(msObj->Map->projection.proj)
&& (line.point[j].x >= -180.0 && line.point[j].x <=
180.0)
&& (line.point[j].y >= -90.0 && line.point[j].y <=
90.0))
msProjectPoint(&(msObj->Map->latlon),
&(msObj->Map->projection),
&line.point[j]); // point is a in lat/lon
#endif
}
cve = msAddLine(&msObj->SelectShape, &line);
msFree(line.point);
msFreeCharArray(tokens, n);
if (cve == -1)
return -1;
msObj->QueryCoordSource = FROMUSERSHAPE;
}
break;
case MSP_IMG_X: // mouse click, in pieces
msObj->ImgPnt.x = atofx(value, &cve);
CONVERSION_ERROR(cve);
if ((msObj->ImgPnt.x > (2*msObj->Map->maxsize)) ||
(msObj->ImgPnt.x < (-2*msObj->Map->maxsize))) {
msSetError(MS_WEBERR, "Coordinate out of range.", "loadForm()");
return -1;
}
msObj->CoordSource = FROMIMGPNT;
msObj->QueryCoordSource = FROMIMGPNT;
break;
case MSP_IMG_Y:
msObj->ImgPnt.y = atofx(value, &cve);
CONVERSION_ERROR(cve);
if ((msObj->ImgPnt.y > (2*msObj->Map->maxsize)) ||
(msObj->ImgPnt.y < (-2*msObj->Map->maxsize))) {
msSetError(MS_WEBERR, "Coordinate out of range.", "loadForm()");
return -1;
}
msObj->CoordSource = FROMIMGPNT;
msObj->QueryCoordSource = FROMIMGPNT;
break;
case MSP_IMGXY: // mouse click, single variable
if(msObj->CoordSource == FROMIMGPNT)
return 0;
tokens = split(value, ' ', &n);
if(!tokens || n != 2) {
msSetError(MS_WEBERR, "Not enough arguments for imgxy.",
"loadForm()");
return -1;
}
msObj->ImgPnt.x = atofx(tokens[0], &cve);
msObj->ImgPnt.y = atofx(tokens[1], &cve);
msFreeCharArray(tokens, 2);
CONVERSION_ERROR(cve);
if ((msObj->ImgPnt.x > (2*msObj->Map->maxsize)) ||
(msObj->ImgPnt.x < (-2*msObj->Map->maxsize)) ||
(msObj->ImgPnt.y > (2*msObj->Map->maxsize)) ||
(msObj->ImgPnt.y < (-2*msObj->Map->maxsize))) {
msSetError(MS_WEBERR, "Reference map coordinate out of range.",
"loadForm()");
return -1;
}
if (msObj->CoordSource == NONE) { // override nothing since this
parameter is usually used to hold a default value
msObj->CoordSource = FROMIMGPNT;
msObj->QueryCoordSource = FROMIMGPNT;
}
break;
case MSP_IMGBOX: // selection box (eg. mouse drag)
tokens = split(value, ' ', &n);
if(!tokens || n != 4) {
msSetError(MS_WEBERR, "Not enough arguments for imgbox.",
"loadForm()");
return -1;
}
msObj->ImgBox.minx = atofx(tokens[0], &cve);
msObj->ImgBox.miny = atofx(tokens[1], &cve);
msObj->ImgBox.maxx = atofx(tokens[2], &cve);
msObj->ImgBox.maxy = atofx(tokens[3], &cve);
msFreeCharArray(tokens, 4);
CONVERSION_ERROR(cve);
if ((msObj->ImgBox.minx != msObj->ImgBox.maxx) &&
(msObj->ImgBox.miny != msObj->ImgBox.maxy)) { // must not
degenerate into a point
msObj->CoordSource = FROMIMGBOX;
msObj->QueryCoordSource = FROMIMGBOX;
}
break;
case MSP_IMGSHAPE: // shape given in image coordinates
{
lineObj line = {0,NULL};
tokens = split(value, ' ', &n);
if((line.point = (pointObj *)malloc(sizeof(pointObj)*(n/2))) ==
NULL) {
msSetError(MS_MEMERR, NULL, "loadForm()");
return -1;
}
line.numpoints = n/2;
msInitShape(&msObj->SelectShape);
msObj->SelectShape.type = MS_SHAPE_POLYGON;
for (j = 0; j < n/2; j++) {
line.point[j].x = atof(tokens[2 * j]);
line.point[j].y = atof(tokens[2 * j + 1]);
}
cve = msAddLine(&msObj->SelectShape, &line);
msFree(line.point);
msFreeCharArray(tokens, n);
if (cve == -1)
return -1;
msObj->QueryCoordSource = FROMIMGSHAPE;
}
break;
case MSP_REF_X: // mouse click in reference image, in pieces
msObj->RefPnt.x = atofx(value, &cve);
CONVERSION_ERROR(cve);
if ((msObj->RefPnt.x > (2 * msObj->Map->maxsize)) ||
(msObj->RefPnt.x < (-2*msObj->Map->maxsize))) {
msSetError(MS_WEBERR, "Coordinate out of range.", "loadForm()");
return -1;
}
msObj->CoordSource = FROMREFPNT;
break;
case MSP_REF_Y:
msObj->RefPnt.y = atofx(value, &cve);
CONVERSION_ERROR(cve);
if((msObj->RefPnt.y > (2 * msObj->Map->maxsize)) ||
(msObj->RefPnt.y < (-2*msObj->Map->maxsize))) {
msSetError(MS_WEBERR, "Coordinate out of range.", "loadForm()");
return -1;
}
msObj->CoordSource = FROMREFPNT;
break;
case MSP_REFXY: /* mouse click in reference image, single variable */
tokens = split(value, ' ', &n);
if(!tokens || n != 2) {
msSetError(MS_WEBERR, "Not enough arguments for imgxy.",
"loadForm()");
return -1;
}
msObj->RefPnt.x = atofx(tokens[0], &cve);
msObj->RefPnt.y = atofx(tokens[1], &cve);
msFreeCharArray(tokens, 2);
CONVERSION_ERROR(cve);
if ((msObj->RefPnt.x > (2 * msObj->Map->maxsize)) ||
(msObj->RefPnt.x < (-2*msObj->Map->maxsize)) || (msObj->RefPnt.y
> (2*msObj->Map->maxsize)) || (msObj->RefPnt.y < (-2*msObj->Map->maxsize)))
{
msSetError(MS_WEBERR, "Reference map coordinate out of range.",
"loadForm()");
return -1;
}
msObj->CoordSource = FROMREFPNT;
break;
case MSP_BUFFER: // radius (map units), actually 1/2 square side
msObj->Buffer = atofx(value, &cve);
CONVERSION_ERROR(cve);
msObj->CoordSource = FROMBUF;
msObj->QueryCoordSource = FROMUSERPNT;
break;
case MSP_SCALE: // scale for new map
msObj->Scale = atofx(value, &cve);
CONVERSION_ERROR(cve);
if (msObj->Scale <= 0) {
msSetError(MS_WEBERR, "Scale out of range.", "loadForm()");
return -1;
}
msObj->CoordSource = FROMSCALE;
msObj->QueryCoordSource = FROMUSERPNT;
break;
case MSP_IMGSIZE: // size of existing image (pixels)
tokens = split(value, ' ', &n);
if(!tokens) {
msSetError(MS_MEMERR, NULL, "loadForm()");
return -1;
}
if (!tokens || n != 2) {
msSetError(MS_WEBERR, "Not enough arguments for imgsize.",
"loadForm()");
return -1;
}
msObj->ImgCols = atoix(tokens[0], &cve);
msObj->ImgRows = atoix(tokens[1], &cve);
msFreeCharArray(tokens, 2);
CONVERSION_ERROR(cve);
if (msObj->ImgCols > msObj->Map->maxsize ||
msObj->ImgRows > msObj->Map->maxsize ||
msObj->ImgCols < 0 || msObj->ImgRows < 0) {
msSetError(MS_WEBERR, "Image size out of range.", "loadForm()");
return -1;
}
break;
case MSP_MAPSIZE: // size of new map (pixels)
tokens = split(value, ' ', &n);
if(!tokens || n != 2) {
msSetError(MS_WEBERR, "Not enough arguments for mapsize.",
"loadForm()");
return -1;
}
msObj->Map->width = atoix(tokens[0], &cve);
msObj->Map->height = atoix(tokens[1], &cve);
msFreeCharArray(tokens, 2);
CONVERSION_ERROR(cve);
if (msObj->Map->width > msObj->Map->maxsize ||
msObj->Map->height > msObj->Map->maxsize ||
msObj->Map->width < 0 || msObj->Map->height < 0) {
msSetError(MS_WEBERR, "Image size out of range.", "loadForm()");
return -1;
}
break;
case MSP_LAYERS: // turn a set of layers, delimited by spaces, on
{
char **layers = split(value, ' ', &n);
for (j = n; j < n; j++)
msObj->Layers[msObj->NumLayers + j] = strdup(layers[j]);
msObj->NumLayers += j;
msFreeCharArray(layers, n);
}
break;
case MSP_LAYER: // turn a single layer/group on
msObj->Layers[msObj->NumLayers] = strdup(value);
msObj->NumLayers++;
break;
case MSP_QLAYER: // layer to query (i.e search)
if (msObj->QueryLayer)
free(msObj->QueryLayer);
msObj->QueryLayer = strdup(value);
break;
case MSP_QITEM: // attribute to query on (optional)
if (msObj->QueryItem)
free(msObj->QueryItem);
msObj->QueryItem = strdup(value);
break;
case MSP_QSTRING: // attribute query string
if (msObj->QueryString)
free(msObj->QueryString);
msObj->QueryString = strdup(value);
break;
case MSP_SLAYER: // layer to select (for feature based search)
if (msObj->SelectLayer)
free(msObj->SelectLayer);
msObj->SelectLayer = strdup(value);
break;
case MSP_SHAPEINDEX: // used for index queries
msObj->ShapeIndex = atoix(value, &cve);
CONVERSION_ERROR(cve);
break;
case MSP_TILEINDEX:
msObj->TileIndex = atoix(value, &cve);
CONVERSION_ERROR(cve);
break;
case MSP_MODE: // set operation mode
kwd = in_word_set(value, strlen(value));
if (!kwd || kwd->type != MST_MODE) {
msSetError(MS_WEBERR, "Invalid mode.", "loadForm()");
return-1;
}
msObj->Mode = kwd->id;
if(msObj->Mode == ZOOMIN) {
msObj->ZoomDirection = 1;
msObj->Mode = BROWSE;
}
else if(msObj->Mode == ZOOMOUT) {
msObj->ZoomDirection = -1;
msObj->Mode = BROWSE;
}
break;
default:
break;
}
return 0;
}
------=_NextPart_000_0059_01C44817.DA87D840
Content-Type: application/x-pkcs7-signature;
name="smime.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="smime.p7s"
MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIJADCCAogw
ggHxoAMCAQICAwxGPTANBgkqhkiG9w0BAQQFADBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhh
d3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVt
YWlsIElzc3VpbmcgQ0EwHhcNMDQwNTA4MTc0OTIyWhcNMDUwNTA4MTc0OTIyWjBpMR8wHQYDVQQD
ExZUaGF3dGUgRnJlZW1haWwgTWVtYmVyMSUwIwYJKoZIhvcNAQkBFhZtbGFkZW4udHVya0BnaXNk
YXRhLmhyMR8wHQYJKoZIhvcNAQkBFhBtdHVya0BhcGFjaGUub3JnMIGfMA0GCSqGSIb3DQEBAQUA
A4GNADCBiQKBgQDDFpTL3QpMpzZNX4hMRwNoTAcJtSF18PnJf3oUryvGmggiy9cbJAuScvfVku2R
DDeBdJaVqDb83nYQydW6JvZI7m2oKApNRV9veadN/T7Fq81QcSBAQgXRyNWCMyl832zOxDrZNchH
kgQzkm67IMHXxDd8LYAxAj8eFFLuV+g29QIDAQABo0UwQzAzBgNVHREELDAqgRZtbGFkZW4udHVy
a0BnaXNkYXRhLmhygRBtdHVya0BhcGFjaGUub3JnMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEE
BQADgYEAtF/h4HA4Zt+3J1a3P0y4Yllqa3srAR+oHJMpQjFLSoUYHkwBQW7iuCWCuzthoIbW/Wuk
g9ww/RSSCJUOFuHham7kClwbWFoRZL9i61L3vfoM3AMKVOj2T0JmoAV+4Ib6lGSaX7DywGbZB5qd
9gpfITF2Cl56XdZ8EXHA2kj2I9cwggMtMIIClqADAgECAgEAMA0GCSqGSIb3DQEBBAUAMIHRMQsw
CQYDVQQGEwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xGjAY
BgNVBAoTEVRoYXd0ZSBDb25zdWx0aW5nMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2Vz
IERpdmlzaW9uMSQwIgYDVQQDExtUaGF3dGUgUGVyc29uYWwgRnJlZW1haWwgQ0ExKzApBgkqhkiG
9w0BCQEWHHBlcnNvbmFsLWZyZWVtYWlsQHRoYXd0ZS5jb20wHhcNOTYwMTAxMDAwMDAwWhcNMjAx
MjMxMjM1OTU5WjCB0TELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UE
BxMJQ2FwZSBUb3duMRowGAYDVQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlm
aWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEkMCIGA1UEAxMbVGhhd3RlIFBlcnNvbmFsIEZyZWVt
YWlsIENBMSswKQYJKoZIhvcNAQkBFhxwZXJzb25hbC1mcmVlbWFpbEB0aGF3dGUuY29tMIGfMA0G
CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDUadfUsJRkW3HpR9gMUbbqcpGwhF59LQ2PexLfhSV1KHQ6
QixjJ5+Ve0vvfhmHHYbqo925zpZkGsIUbkSsfOaP6E0PcR9AOKYAo4d49vmUhl6t6sBeduvZFKNd
bnp8DKVLVX8GGSl/npom1Wq7OCQIapjHsdqjmJH9edvlWsQcuQIDAQABoxMwETAPBgNVHRMBAf8E
BTADAQH/MA0GCSqGSIb3DQEBBAUAA4GBAMfskn5O+PWWpWdiKqTwTRFg0G+NYFhhrCa7UjVcCM8w
+6hKloofYkIjjBcP9LpknBesRynfnZhe0mxgcVyirNx54+duAEcftQ0o6AKd5Jr9E/Sm2Xyx+Nxf
IyYJkYBz0BQb3kOpgyXy5pwvFcr+pquKB3WLDN1RhGvk+NHOd6KBMIIDPzCCAqigAwIBAgIBDTAN
BgkqhkiG9w0BAQUFADCB0TELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAG
A1UEBxMJQ2FwZSBUb3duMRowGAYDVQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2Vy
dGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEkMCIGA1UEAxMbVGhhd3RlIFBlcnNvbmFsIEZy
ZWVtYWlsIENBMSswKQYJKoZIhvcNAQkBFhxwZXJzb25hbC1mcmVlbWFpbEB0aGF3dGUuY29tMB4X
DTAzMDcxNzAwMDAwMFoXDTEzMDcxNjIzNTk1OVowYjELMAkGA1UEBhMCWkExJTAjBgNVBAoTHFRo
YXd0ZSBDb25zdWx0aW5nIChQdHkpIEx0ZC4xLDAqBgNVBAMTI1RoYXd0ZSBQZXJzb25hbCBGcmVl
bWFpbCBJc3N1aW5nIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEpjxVc1X7TrnKmVoe
aMB1BHCd3+n/ox7svc31W/Iadr1/DDph8r9RzgHU5VAKMNcCY1osiRVwjt3J8CuFWqo/cVbLrzwL
B+fxH5E2JCoTzyvV84J3PQO+K/67GD4Hv0CAAmTXp6a7n2XRxSpUhQ9IBH+nttE8YQRAHmQZcmC3
+wIDAQABo4GUMIGRMBIGA1UdEwEB/wQIMAYBAf8CAQAwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDov
L2NybC50aGF3dGUuY29tL1RoYXd0ZVBlcnNvbmFsRnJlZW1haWxDQS5jcmwwCwYDVR0PBAQDAgEG
MCkGA1UdEQQiMCCkHjAcMRowGAYDVQQDExFQcml2YXRlTGFiZWwyLTEzODANBgkqhkiG9w0BAQUF
AAOBgQBIjNFQg+oLLswNo2asZw9/r6y+whehQ5aUnX9MIbj4Nh+qLZ82L8D0HFAgk3A8/a3hYWLD
2ToZfoSxmRsAxRoLgnSeJVCUYsfbJ3FXJY3dqZw5jowgT2Vfldr394fWxghOrvbqNOUQGls1TXfj
ViF4gtwhGTXeJLHTHUb/XV9lTzGCAs8wggLLAgEBMGkwYjELMAkGA1UEBhMCWkExJTAjBgNVBAoT
HFRoYXd0ZSBDb25zdWx0aW5nIChQdHkpIEx0ZC4xLDAqBgNVBAMTI1RoYXd0ZSBQZXJzb25hbCBG
cmVlbWFpbCBJc3N1aW5nIENBAgMMRj0wCQYFKw4DAhoFAKCCAbwwGAYJKoZIhvcNAQkDMQsGCSqG
SIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMDQwNjAxMTgzNDM2WjAjBgkqhkiG9w0BCQQxFgQUnSNz
OxOEg1fdEU3f+J0GpjqF64UwZwYJKoZIhvcNAQkPMVowWDAKBggqhkiG9w0DBzAOBggqhkiG9w0D
AgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgwBwYFKw4DAhowCgYI
KoZIhvcNAgUweAYJKwYBBAGCNxAEMWswaTBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3Rl
IENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVtYWls
IElzc3VpbmcgQ0ECAwxGPTB6BgsqhkiG9w0BCRACCzFroGkwYjELMAkGA1UEBhMCWkExJTAjBgNV
BAoTHFRoYXd0ZSBDb25zdWx0aW5nIChQdHkpIEx0ZC4xLDAqBgNVBAMTI1RoYXd0ZSBQZXJzb25h
bCBGcmVlbWFpbCBJc3N1aW5nIENBAgMMRj0wDQYJKoZIhvcNAQEBBQAEgYAoT/wDEapJx57VVNd4
EIFbmMjFqHckkS6kQLQYDGywaIWEsvlEMU0c12jOcSP+EyzdxYgDapLyOaIBJOq6RhnhkNPw7pNL
fUnyOxatvi03KcBT+5CdYH7nCBvf4kdBuFM6nNJJ9jF6rfhkjnC1VRcTn7twOgHVtEGZOvcqpVXP
yQAAAAAAAA==
------=_NextPart_000_0059_01C44817.DA87D840--
More information about the mapserver-dev
mailing list