1 /******************************************************************************
2  * $Id$
3  *
4  * Project:  MapServer
5  * Purpose:  Functions for operating on a classObj that don't belong in a
6  *           more specific file such as mapfile.c.
7  *           Adapted from mapobject.c.
8  * Author:   Sean Gillies, sgillies@frii.com
9  *
10  ******************************************************************************
11  * Copyright (c) 2004, Sean Gillies
12  *
13  * Permission is hereby granted, free of charge, to any person obtaining a
14  * copy of this software and associated documentation files (the "Software"),
15  * to deal in the Software without restriction, including without limitation
16  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17  * and/or sell copies of the Software, and to permit persons to whom the
18  * Software is furnished to do so, subject to the following conditions:
19  *
20  * The above copyright notice and this permission notice shall be included in
21  * all copies of this Software or works derived from this Software.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29  * DEALINGS IN THE SOFTWARE.
30  ****************************************************************************/
31 
32 #include "mapserver.h"
33 
34 
35 /*
36 ** Add a label to a classObj (order doesn't matter for labels like it does with styles)
37 */
msAddLabelToClass(classObj * class,labelObj * label)38 int msAddLabelToClass(classObj *class, labelObj *label)
39 {
40   if (!label) {
41     msSetError(MS_CHILDERR, "Can't add a NULL label.", "msAddLabelToClass()");
42     return MS_FAILURE;
43   }
44   if (msGrowClassLabels(class) == NULL) return MS_FAILURE;
45 
46   /* msGrowClassLabels will alloc the label, free it in this case */
47   free(class->labels[class->numlabels]);
48   class->labels[class->numlabels] = label;
49   MS_REFCNT_INCR(label);
50   class->numlabels++;
51   return MS_SUCCESS;
52 }
53 
54 /*
55 ** Remove a label from a classObj.
56 */
msRemoveLabelFromClass(classObj * class,int nLabelIndex)57 labelObj *msRemoveLabelFromClass(classObj *class, int nLabelIndex)
58 {
59   int i;
60   labelObj *label;
61 
62   if (nLabelIndex < 0 || nLabelIndex >= class->numlabels) {
63     msSetError(MS_CHILDERR, "Cannot remove label, invalid index %d", "msRemoveLabelFromClass()", nLabelIndex);
64     return NULL;
65   } else {
66     label=class->labels[nLabelIndex];
67     for (i=nLabelIndex; i<class->numlabels-1; i++) {
68       class->labels[i]=class->labels[i+1];
69     }
70     class->labels[class->numlabels-1]=NULL;
71     class->numlabels--;
72     MS_REFCNT_DECR(label);
73     return label;
74   }
75 }
76 
77 /**
78  * Move the style up inside the array of styles.
79  */
msMoveStyleUp(classObj * class,int nStyleIndex)80 int msMoveStyleUp(classObj *class, int nStyleIndex)
81 {
82   styleObj *psTmpStyle = NULL;
83   if (class && nStyleIndex < class->numstyles && nStyleIndex >0) {
84     psTmpStyle = (styleObj *)malloc(sizeof(styleObj));
85     initStyle(psTmpStyle);
86 
87     msCopyStyle(psTmpStyle, class->styles[nStyleIndex]);
88 
89     msCopyStyle(class->styles[nStyleIndex],
90                 class->styles[nStyleIndex-1]);
91 
92     msCopyStyle(class->styles[nStyleIndex-1], psTmpStyle);
93 
94     return(MS_SUCCESS);
95   }
96   msSetError(MS_CHILDERR, "Invalid index: %d", "msMoveStyleUp()",
97              nStyleIndex);
98   return (MS_FAILURE);
99 }
100 
101 
102 /**
103  * Move the style down inside the array of styles.
104  */
msMoveStyleDown(classObj * class,int nStyleIndex)105 int msMoveStyleDown(classObj *class, int nStyleIndex)
106 {
107   styleObj *psTmpStyle = NULL;
108 
109   if (class && nStyleIndex < class->numstyles-1 && nStyleIndex >=0) {
110     psTmpStyle = (styleObj *)malloc(sizeof(styleObj));
111     initStyle(psTmpStyle);
112 
113     msCopyStyle(psTmpStyle, class->styles[nStyleIndex]);
114 
115     msCopyStyle(class->styles[nStyleIndex],
116                 class->styles[nStyleIndex+1]);
117 
118     msCopyStyle(class->styles[nStyleIndex+1], psTmpStyle);
119 
120     return(MS_SUCCESS);
121   }
122   msSetError(MS_CHILDERR, "Invalid index: %d", "msMoveStyleDown()",
123              nStyleIndex);
124   return (MS_FAILURE);
125 }
126 
127 /* Moved here from mapscript.i
128  *
129  * Returns the index at which the style was inserted
130  *
131  */
msInsertStyle(classObj * class,styleObj * style,int nStyleIndex)132 int msInsertStyle(classObj *class, styleObj *style, int nStyleIndex)
133 {
134   int i;
135 
136   if (!style) {
137     msSetError(MS_CHILDERR, "Can't insert a NULL Style", "msInsertStyle()");
138     return -1;
139   }
140 
141   /* Ensure there is room for a new style */
142   if (msGrowClassStyles(class) == NULL) {
143     return -1;
144   }
145   /* Catch attempt to insert past end of styles array */
146   else if (nStyleIndex >= class->numstyles) {
147     msSetError(MS_CHILDERR, "Cannot insert style beyond index %d", "insertStyle()", class->numstyles-1);
148     return -1;
149   } else if (nStyleIndex < 0) { /* Insert at the end by default */
150     class->styles[class->numstyles]=style;
151     MS_REFCNT_INCR(style);
152     class->numstyles++;
153     return class->numstyles-1;
154   } else if (nStyleIndex >= 0 && nStyleIndex < class->numstyles) {
155     /* Move styles existing at the specified nStyleIndex or greater */
156     /* to a higher nStyleIndex */
157     for (i=class->numstyles-1; i>=nStyleIndex; i--) {
158       class->styles[i+1] = class->styles[i];
159     }
160     class->styles[nStyleIndex]=style;
161     MS_REFCNT_INCR(style);
162     class->numstyles++;
163     return nStyleIndex;
164   } else {
165     msSetError(MS_CHILDERR, "Invalid nStyleIndex", "insertStyle()");
166     return -1;
167   }
168 }
169 
msRemoveStyle(classObj * class,int nStyleIndex)170 styleObj *msRemoveStyle(classObj *class, int nStyleIndex)
171 {
172   int i;
173   styleObj *style;
174   if (nStyleIndex < 0 || nStyleIndex >= class->numstyles) {
175     msSetError(MS_CHILDERR, "Cannot remove style, invalid nStyleIndex %d", "removeStyle()", nStyleIndex);
176     return NULL;
177   } else {
178     style=class->styles[nStyleIndex];
179     for (i=nStyleIndex; i<class->numstyles-1; i++) {
180       class->styles[i]=class->styles[i+1];
181     }
182     class->styles[class->numstyles-1]=NULL;
183     class->numstyles--;
184     MS_REFCNT_DECR(style);
185     return style;
186   }
187 }
188 
189 /**
190  * Delete the style identified by the index and shift
191  * styles that follows the deleted style.
192  */
msDeleteStyle(classObj * class,int nStyleIndex)193 int msDeleteStyle(classObj *class, int nStyleIndex)
194 {
195   int i = 0;
196   if (class && nStyleIndex < class->numstyles && nStyleIndex >=0) {
197     if (freeStyle(class->styles[nStyleIndex]) == MS_SUCCESS)
198       msFree(class->styles[nStyleIndex]);
199     for (i=nStyleIndex; i< class->numstyles-1; i++) {
200       class->styles[i] = class->styles[i+1];
201     }
202     class->styles[class->numstyles-1] = NULL;
203     class->numstyles--;
204     return(MS_SUCCESS);
205   }
206   msSetError(MS_CHILDERR, "Invalid index: %d", "msDeleteStyle()",
207              nStyleIndex);
208   return (MS_FAILURE);
209 }
210