[mapserver-commits] r10107 - trunk/mapserver

svn at osgeo.org svn at osgeo.org
Tue Apr 20 00:20:31 EDT 2010


Author: sdlime
Date: 2010-04-20 00:20:31 -0400 (Tue, 20 Apr 2010)
New Revision: 10107

Modified:
   trunk/mapserver/HISTORY.TXT
   trunk/mapserver/maplayer.c
Log:
Reverted msLayerWhichItems() to 5.4-like behavior although still supporting retrieving all items (#3356,#3342)

Modified: trunk/mapserver/HISTORY.TXT
===================================================================
--- trunk/mapserver/HISTORY.TXT	2010-04-20 04:19:06 UTC (rev 10106)
+++ trunk/mapserver/HISTORY.TXT	2010-04-20 04:20:31 UTC (rev 10107)
@@ -14,6 +14,9 @@
 Current Version (SVN trunk):
 ----------------------------
 
+- Reverted msLayerWhichItems() to 5.4-like behavior although still supporting
+  retrieving all items (#3356,#3342)
+
 - Grid layer: remove drawing of unnecessary gird lines (#3433) 
 
 - Avoid errors and debug output for CONNECTION-less OGR layers in mappool.c

Modified: trunk/mapserver/maplayer.c
===================================================================
--- trunk/mapserver/maplayer.c	2010-04-20 04:19:06 UTC (rev 10106)
+++ trunk/mapserver/maplayer.c	2010-04-20 04:20:31 UTC (rev 10107)
@@ -294,169 +294,196 @@
 {
   int i;
 
-  for(i=0; i<(*listsize); i++) {
-    if(strcasecmp(list[i], string) == 0) return(i);
-  }
+  for(i=0; i<(*listsize); i++)
+    if(strcasecmp(list[i], string) == 0) {
+      /* printf("string2list (duplicate): %s %d\n", string, i); */
+      return(i);
+    }
 
   list[i] = strdup(string);
   (*listsize)++;
 
+  /* printf("string2list: %s %d\n", string, i); */
+
   return(i);
 }
 
-static void expression2list(char **items, int numitems, char **list, int *listsize, expressionObj *exp)
+/* TO DO: this function really needs to use the lexer */
+static void expression2list(char **list, int *listsize, expressionObj *expression)
 {
-  int i, t, index;
-  char *tag, *expptr;
-  int taglen;
+  int i, j, l;
+  char tmpstr1[1024], tmpstr2[1024];
+  short in=MS_FALSE;
+  int tmpint;
 
-  for(i=0; i<numitems; i++) {
-    tag = (char *) malloc(sizeof(char)*strlen(items[i])+3);
-    sprintf(tag, "[%s]", items[i]); /* there is enough room in tag */
-    if((expptr = (char *) msCaseFindSubstring(exp->string, tag)) != 0) {      
-      index = string2list(list, listsize, items[i]); /* add to overall list */
+  j = 0;
+  l = strlen(expression->string);
+  for(i=0; i<l; i++) {
+    if(expression->string[i] == '[') {
+      in = MS_TRUE;
+      tmpstr2[j] = expression->string[i];
+      j++;
+      continue;
+    }
+    if(expression->string[i] == ']') {
+      in = MS_FALSE;
 
-      t = exp->numitems; /* we need to know if the tag list changes */
-      string2list(exp->items, &(exp->numitems), tag); /* add tag to expression list, use tag so we don't have to reconstruct it later */
-      if(t != exp->numitems) exp->indexes[exp->numitems-1] = index; /* index to overall list */
+      tmpint = expression->numitems;
 
-      /* normalize expression */
-      taglen = strlen(tag);
-      do {
-	memcpy(expptr, tag, taglen);
-      } while((expptr = (char *) msCaseFindSubstring(expptr+taglen, tag)) != 0);
-    }
-    free(tag);
-  }
-}
+      tmpstr2[j] = expression->string[i];
+      tmpstr2[j+1] = '\0';
+      string2list(expression->items, &(expression->numitems), tmpstr2);
 
-static int allocateExpressionItems(expressionObj *exp, int numitems)
-{
-  exp->items = (char **) calloc(numitems, sizeof(char *));
-  if(!(exp->items)) {
-    msSetError(MS_MEMERR, NULL, "allocateExpressionItems()");
-    return MS_FAILURE;
-  }
-  exp->indexes = (int *) malloc(numitems*sizeof(int));
-  if(!(exp->indexes)) {
-    msSetError(MS_MEMERR, NULL, "allocateExpressionItems()");
-    return MS_FAILURE;
-  }
-  exp->numitems = 0; /* initially empty */
+      if(tmpint != expression->numitems) { /* not a duplicate, so no need to calculate the index */
+        tmpstr1[j-1] = '\0';
+        expression->indexes[expression->numitems - 1] = string2list(list, listsize, tmpstr1);
+      }
 
-  return MS_SUCCESS; 
-}
+      j = 0; /* reset */
 
-static int isValidItem(char **list, int listsize, char *item) 
-{
-  int i;
+      continue;
+    }
 
-  for(i=0; i<listsize; i++) {
-    if(strcasecmp(list[i], item) == 0) return MS_TRUE; /* found it */
+    if(in) {
+      tmpstr2[j] = expression->string[i];
+      tmpstr1[j-1] = expression->string[i];
+      j++;
+    }
   }
-
-  msSetError(MS_MISCERR, "Item %s not found", "isValidItem()", item);
-  return MS_FALSE;
 }
 
+
+/*                                                                                                                                                                                                                                        
+** This function builds a list of items necessary to draw or query a particular layer by                                                                                                                                                  
+** examining the contents of the various xxxxitem parameters and expressions. That list is                                                                                                                                                
+** then used to set the iteminfo variable.                                                                                                                                                                                                
+*/
 int msLayerWhichItems(layerObj *layer, int get_all, char *metadata)
 {
-  char **items;
-  int numitems;
   int i, j, k, rv;
-  int freeitems=MS_FALSE;
+  int nt=0, ne=0;
 
   if (!layer->vtable) {
     rv =  msInitializeVirtualTable(layer);
     if (rv != MS_SUCCESS) return rv;
   }
 
-  /* force get_all=MS_TRUE in some cases */
-  if(layer->connectiontype == MS_INLINE || layer->connectiontype == MS_SDE ||
-     (layer->connectiontype == MS_ORACLESPATIAL && layer->data && msCaseFindSubstring(layer->data, "UNIQUE")))
-    get_all=MS_TRUE;
-
-  /*
-  ** The algorithm:
-  **   1) call msLayerGetItems to get a complete list (including joins potentially)
-  **   2) loop though item-based parameters and expressions to identify items to keep 
-  **   3) based on 2) build a list of items 
-  */
-
-  rv = msLayerGetItems(layer);
-  if(rv != MS_SUCCESS) return rv;
-
-  if(layer->numitems == 0) return MS_SUCCESS; /* nothing to do but not an error */
-
-  items = layer->items; /* save for later */
-  numitems = layer->numitems;
-
-  /*
-  ** reset things (if necessary)
-  **   note: if we don't reset then the items array is fully populated will ALL items
-  */
-  if(!get_all) {    
-    rv = layer->vtable->LayerCreateItems(layer, numitems);
-    if(rv != MS_SUCCESS) return rv;
-    freeitems = MS_TRUE;
+  /* Cleanup any previous item selection */
+  msLayerFreeItemInfo(layer);
+  if(layer->items) {
+    msFreeCharArray(layer->items, layer->numitems);
+    layer->items = NULL;
+    layer->numitems = 0;
   }
 
-  /* layer-level item use */
-  if(layer->classitem) {
-    if(!isValidItem(items, numitems, layer->classitem)) return MS_FAILURE;
-    layer->classitemindex = string2list(layer->items, &(layer->numitems), layer->classitem);
-  }
-  if(layer->filteritem) {
-    if(!isValidItem(items, numitems, layer->filteritem)) return MS_FAILURE;
-    layer->filteritemindex = string2list(layer->items, &(layer->numitems), layer->filteritem);
-  }
-  if(layer->labelitem) {
-    if(!isValidItem(items, numitems, layer->labelitem)) return MS_FAILURE;
-    layer->labelitemindex = string2list(layer->items, &(layer->numitems), layer->labelitem);
-  }
+  /* layer level counts */
+  if(layer->classitem) nt++;
+  if(layer->filteritem) nt++;
 
+  ne = 0;
   if(layer->filter.type == MS_EXPRESSION) {
-    if(allocateExpressionItems(&layer->filter, numitems) != MS_SUCCESS) return MS_FAILURE;
-    expression2list(items, numitems, layer->items, &(layer->numitems), &(layer->filter));
+    ne = msCountChars(layer->filter.string, '[');
+    if(ne > 0) {
+      layer->filter.items = (char **) calloc(ne, sizeof(char *)); /* should be more than enough space */
+      if(!(layer->filter.items)) {
+        msSetError(MS_MEMERR, NULL, "msLayerWhichItems()");
+        return(MS_FAILURE);
+      }
+      layer->filter.indexes = (int *) malloc(ne*sizeof(int));
+      if(!(layer->filter.indexes)) {
+        msSetError(MS_MEMERR, NULL, "msLayerWhichItems()");
+        return(MS_FAILURE);
+      }
+      layer->filter.numitems = 0;
+      nt += ne;
+    }
   }
 
-  /* class-level item use */
+  if(layer->labelitem) nt++;
+
+  /* class level counts */
   for(i=0; i<layer->numclasses; i++) {
+
+    for(j=0; j<layer->class[i]->numstyles; j++) {
+      if(layer->class[i]->styles[j]->rangeitem) nt++;
+      nt += layer->class[i]->styles[j]->numbindings;
+    }
+
+    ne = 0;
     if(layer->class[i]->expression.type == MS_EXPRESSION) {
-      if(allocateExpressionItems(&layer->class[i]->expression, numitems) != MS_SUCCESS) return MS_FAILURE;
-      expression2list(items, numitems, layer->items, &(layer->numitems), &(layer->class[i]->expression));
+      ne = msCountChars(layer->class[i]->expression.string, '[');
+      if(ne > 0) {
+        layer->class[i]->expression.items = (char **) calloc(ne, sizeof(char *)); /* should be more than enough space */
+        if(!(layer->class[i]->expression.items)) {
+          msSetError(MS_MEMERR, NULL, "msLayerWhichItems()");
+          return(MS_FAILURE);
+        }
+        layer->class[i]->expression.indexes = (int *) malloc(ne*sizeof(int));
+        if(!(layer->class[i]->expression.indexes)) {
+          msSetError(MS_MEMERR, NULL, "msLayerWhichItems()");
+          return(MS_FAILURE);
+        }
+        layer->class[i]->expression.numitems = 0;
+        nt += ne;
+      }
     }
 
+    nt += layer->class[i]->label.numbindings;
+
+    ne = 0;
     if(layer->class[i]->text.type == MS_EXPRESSION) {
-      if(allocateExpressionItems(&layer->class[i]->text, numitems) != MS_SUCCESS) return MS_FAILURE;
-      expression2list(items, numitems, layer->items, &(layer->numitems), &(layer->class[i]->text));
+      ne = msCountChars(layer->class[i]->text.string, '[');
+      if(ne > 0) {
+        layer->class[i]->text.items = (char **) calloc(ne, sizeof(char *)); /* should be more than enough space */
+        if(!(layer->class[i]->text.items)) {
+          msSetError(MS_MEMERR, NULL, "msLayerWhichItems()");
+          return(MS_FAILURE);
+        }
+        layer->class[i]->text.indexes = (int *) malloc(ne*sizeof(int));
+        if(!(layer->class[i]->text.indexes)) {
+          msSetError(MS_MEMERR, NULL, "msLayerWhichItems()");
+          return(MS_FAILURE);
+        }
+        layer->class[i]->text.numitems = 0;
+        nt += ne;
+      }
     }
+  }
 
-    for(k=0; k<MS_LABEL_BINDING_LENGTH; k++) {      
-      if(layer->class[i]->label.bindings[k].item) {
-        if(!isValidItem(items, numitems, layer->class[i]->label.bindings[k].item)) return MS_FAILURE;
-        layer->class[i]->label.bindings[k].index = string2list(layer->items, &(layer->numitems), layer->class[i]->label.bindings[k].item);
+  /* always retrieve all items in some cases */
+  if(layer->connectiontype == MS_INLINE || get_all == MS_TRUE) {
+    msLayerGetItems(layer);
+    if(nt > 0) /* need to realloc the array to accept the possible new items*/
+      layer->items = (char **)realloc(layer->items, sizeof(char *)*(layer->numitems + nt));
+  } else {
+    rv = layer->vtable->LayerCreateItems(layer, nt);
+    if(rv != MS_SUCCESS)
+      return rv;
+  }
+
+  if(nt > 0) {
+    if(layer->classitem) layer->classitemindex = string2list(layer->items, &(layer->numitems), layer->classitem);
+    if(layer->filteritem) layer->filteritemindex = string2list(layer->items, &(layer->numitems), layer->filteritem);
+
+    for(i=0; i<layer->numclasses; i++) {
+      if(layer->class[i]->expression.type == MS_EXPRESSION) expression2list(layer->items, &(layer->numitems), &(layer->class[i]->expression));
+      for(j=0; j<layer->class[i]->numstyles; j++) {
+        if(layer->class[i]->styles[j]->rangeitem) layer->class[i]->styles[j]->rangeitemindex = string2list(layer->items, &(layer->numitems), layer->class[i]->styles[j]->rangeitem);
+        for(k=0; k<MS_STYLE_BINDING_LENGTH; k++)
+          if(layer->class[i]->styles[j]->bindings[k].item) layer->class[i]->styles[j]->bindings[k].index = string2list(layer->items, &(layer->numitems), layer->class[i]->styles[j]->bindings[k].item);
       }
     }
 
-    /* style-level item use */
-    for(j=0; j<layer->class[i]->numstyles; j++) {
-      if(layer->class[i]->styles[j]->rangeitem) {
-        if(!isValidItem(items, numitems, layer->class[i]->styles[j]->rangeitem)) return MS_FAILURE;
-        layer->class[i]->styles[j]->rangeitemindex = string2list(layer->items, &(layer->numitems), layer->class[i]->styles[j]->rangeitem);
-      }
-      for(k=0; k<MS_STYLE_BINDING_LENGTH; k++) {
-	if(layer->class[i]->styles[j]->bindings[k].item) {
-          if(!isValidItem(items, numitems, layer->class[i]->styles[j]->bindings[k].item)) return MS_FAILURE;
-          layer->class[i]->styles[j]->bindings[k].index = string2list(layer->items, &(layer->numitems), layer->class[i]->styles[j]->bindings[k].item);
-        }
-      }
+    if(layer->filter.type == MS_EXPRESSION) expression2list(layer->items, &(layer->numitems), &(layer->filter));
+
+    if(layer->labelitem) layer->labelitemindex = string2list(layer->items, &(layer->numitems), layer->labelitem);
+    for(i=0; i<layer->numclasses; i++) {
+      if(layer->class[i]->text.type == MS_EXPRESSION) expression2list(layer->items, &(layer->numitems), &(layer->class[i]->text));
+      for(k=0; k<MS_LABEL_BINDING_LENGTH; k++)
+        if(layer->class[i]->label.bindings[k].item) layer->class[i]->label.bindings[k].index = string2list(layer->items, &(layer->numitems), layer->class[i]->label.bindings[k].item);
     }
   }
 
-  /*
-  ** need a description here of what this code is doing...
-  */ 
   if(metadata) {
     char **tokens;
     int n = 0;
@@ -484,16 +511,11 @@
     }
   }
 
-  /*
-  ** Clean up (if necessary)
-  */
-  if(freeitems) msFreeCharArray(items, numitems);
-
   /* populate the iteminfo array */
   if(layer->numitems == 0)
-    return MS_SUCCESS;
-  else
-    return msLayerInitItemInfo(layer);
+    return(MS_SUCCESS);
+
+  return(msLayerInitItemInfo(layer));
 }
 
 /*



More information about the mapserver-commits mailing list