1 /******************************************************************************
2  * $Id$
3  *
4  * Project: MapServer
5  * Purpose: Functions to allow copying/cloning of maps
6  * Author:  Sean Gillies, sgillies@frii.com
7  *
8  * Notes:
9  * These functions are not in mapfile.c because that file is
10  * cumbersome enough as it is.  There is agreement that this code and
11  * that in mapfile.c should eventually be split up by object into
12  * mapobj.c, layerobj.c, etc.  Or something like that.
13  *
14  * Unit tests are written in Python using PyUnit and are in
15  * mapscript/python/tests/testCopyMap.py.  The tests can be
16  * executed from the python directory as
17  *
18  *   python2 tests/testCopyMap.py
19  *
20  * I just find Python to be very handy for unit testing, that's all.
21  *
22  ******************************************************************************
23  * Copyright (c) 1996-2005 Regents of the University of Minnesota.
24  *
25  * Permission is hereby granted, free of charge, to any person obtaining a
26  * copy of this software and associated documentation files (the "Software"),
27  * to deal in the Software without restriction, including without limitation
28  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
29  * and/or sell copies of the Software, and to permit persons to whom the
30  * Software is furnished to do so, subject to the following conditions:
31  *
32  * The above copyright notice and this permission notice shall be included in
33  * all copies of this Software or works derived from this Software.
34  *
35  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
36  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
37  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
38  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
39  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
40  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
41  * DEALINGS IN THE SOFTWARE.
42  ****************************************************************************/
43 
44 #include <assert.h>
45 #include "mapserver.h"
46 #include "mapsymbol.h"
47 
48 #include "mapcopy.h"
49 
50 /***********************************************************************
51  * msCopyProjectioExtended()                                           *
52  *                                                                     *
53  * Copy a projectionObj while adding additional arguments              *
54  **********************************************************************/
55 
msCopyProjectionExtended(projectionObj * dst,projectionObj * src,char ** args,int num_args)56 int msCopyProjectionExtended(projectionObj *dst, projectionObj *src, char ** args, int num_args)
57 {
58 
59   int i;
60 
61   MS_COPYSTELEM(numargs);
62   MS_COPYSTELEM(gt);
63   MS_COPYSTELEM(automatic);
64 
65   for (i = 0; i < dst->numargs; i++) {
66     /* Our destination consists of unallocated pointers */
67     dst->args[i] = msStrdup(src->args[i]);
68   }
69   for(i=0 ; i< num_args; i++) {
70     dst->args[dst->numargs++] = msStrdup(args[i]);
71   }
72   msProjectionInheritContextFrom(dst, src);
73   if (dst->numargs != 0) {
74     if (msProcessProjection(dst) != MS_SUCCESS)
75       return MS_FAILURE;
76   }
77   MS_COPYSTELEM(wellknownprojection);
78   return MS_SUCCESS;
79 }
80 
81 /***********************************************************************
82  * msCopyProjection()                                                  *
83  *                                                                     *
84  * Copy a projectionObj                                                *
85  **********************************************************************/
86 
msCopyProjection(projectionObj * dst,projectionObj * src)87 int msCopyProjection(projectionObj *dst, projectionObj *src)
88 {
89   return msCopyProjectionExtended(dst,src,NULL,0);
90 }
91 
92 /***********************************************************************
93  * msCopyLine()                                                        *
94  *                                                                     *
95  * Copy a lineObj, using msCopyPoint()                                 *
96  **********************************************************************/
msCopyLine(lineObj * dst,lineObj * src)97 int msCopyLine(lineObj *dst, lineObj *src)
98 {
99 
100   int i;
101 
102   dst->numpoints = src->numpoints;
103   for (i = 0; i < dst->numpoints; i++) {
104     MS_COPYPOINT(&(dst->point[i]), &(src->point[i]));
105   }
106 
107   return MS_SUCCESS;
108 }
109 
110 /***********************************************************************
111  * msCopyShape()                                                       *
112  *                                                                     *
113  * Copy a shapeObj, using msCopyLine(), msCopyRect()                   *
114  * Not completely implemented or tested.                               *
115  **********************************************************************/
116 /*
117 int msCopyShapeObj(shapeObj *dst, shapeObj *src) {
118   int i;
119   copyProperty(&(dst->numlines), &(src->numlines), sizeof(int));
120   for (i = 0; i < dst->numlines; i++) {
121     msCopyLine(&(dst->line[i]), &(src->line[i]));
122   }
123   msCopyRect(&(dst->bounds), &(src->bounds));
124   copyProperty(&(dst->type), &(src->type), sizeof(int));
125   copyProperty(&(dst->index), &(src->index), sizeof(long));
126   copyProperty(&(dst->tileindex), &(src->tileindex), sizeof(int));
127   copyProperty(&(dst->classindex), &(src->classindex), sizeof(int));
128   copyStringPropertyRealloc(&(dst->text), src->text);
129   copyProperty(&(dst->numvalues), &(src->numvalues), sizeof(int));
130   for (i = 0; i < dst->numvalues; i++) {
131     copyStringPropertyRealloc(&(dst->values[i]), src->values[i]);
132   }
133 
134   return(0);
135 }
136 */
137 
138 /**********************************************************************
139  * msCopyItem()                                                        *
140  *                                                                     *
141  * Copy an itemObj                                                     *
142  **********************************************************************/
143 
msCopyItem(itemObj * dst,itemObj * src)144 int msCopyItem(itemObj *dst, itemObj *src)
145 {
146 
147   MS_COPYSTRING(dst->name, src->name);
148   MS_COPYSTELEM(type);
149   MS_COPYSTELEM(index);
150   MS_COPYSTELEM(size);
151   MS_COPYSTELEM(numdecimals);
152 
153   return MS_SUCCESS;
154 }
155 
156 /***********************************************************************
157  * msCopyHashTable()                                                   *
158  *                                                                     *
159  * Copy a hashTableObj, using msInsertHashTable()                      *
160  **********************************************************************/
161 
msCopyHashTable(hashTableObj * dst,hashTableObj * src)162 int msCopyHashTable(hashTableObj *dst, hashTableObj *src)
163 {
164   const char *key=NULL;
165   while (1) {
166     key = msNextKeyFromHashTable(src, key);
167     if (!key)
168       break;
169     else
170       msInsertHashTable(dst, key, msLookupHashTable(src, key));
171   }
172   return MS_SUCCESS;
173 }
174 
175 /***********************************************************************
176  * msCopyFontSet()                                                     *
177  *                                                                     *
178  * Copy a fontSetObj, using msCreateHashTable() and msCopyHashTable()  *
179  **********************************************************************/
180 
msCopyFontSet(fontSetObj * dst,fontSetObj * src,mapObj * map)181 int msCopyFontSet(fontSetObj *dst, fontSetObj *src, mapObj *map)
182 {
183 
184   MS_COPYSTRING(dst->filename, src->filename);
185   MS_COPYSTELEM(numfonts);
186   if (&(src->fonts)) {
187     /* if (!dst->fonts) */
188     /* dst->fonts = msCreateHashTable(); */
189     if (msCopyHashTable(&(dst->fonts), &(src->fonts)) != MS_SUCCESS)
190       return MS_FAILURE;
191   }
192 
193   dst->map = map;
194 
195   return MS_SUCCESS;
196 }
197 
198 /***********************************************************************
199  * msCopyExpression()                                                  *
200  *                                                                     *
201  * Copy an expressionObj, but only its string, type and flags          *
202  **********************************************************************/
203 
msCopyExpression(expressionObj * dst,expressionObj * src)204 int msCopyExpression(expressionObj *dst, expressionObj *src)
205 {
206   if((dst->type == MS_REGEX) && dst->compiled) ms_regfree(&(dst->regex));
207   dst->compiled = MS_FALSE;
208 
209   MS_COPYSTRING(dst->string, src->string);
210   MS_COPYSTELEM(type);
211   MS_COPYSTELEM(flags);
212 
213   return MS_SUCCESS;
214 }
215 
216 /***********************************************************************
217  * msCopyJoin()                                                        *
218  *                                                                     *
219  * Copy a joinObj                                                      *
220  **********************************************************************/
221 
msCopyJoin(joinObj * dst,joinObj * src)222 int msCopyJoin(joinObj *dst, joinObj *src)
223 {
224   MS_COPYSTRING(dst->name, src->name);
225 
226   /* makes no sense to copy the items or values
227      since they are runtime additions to the mapfile */
228 
229   MS_COPYSTRING(dst->table, src->table);
230   MS_COPYSTRING(dst->from, src->from);
231   MS_COPYSTRING(dst->to, src->to);
232   MS_COPYSTRING(dst->header, src->header);
233 #ifndef __cplusplus
234   MS_COPYSTRING(dst->template, src->template);
235 #else
236   MS_COPYSTRING(dst->_template, src->_template);
237 #endif
238   MS_COPYSTRING(dst->footer, src->footer);
239   dst->type = src->type;
240   MS_COPYSTRING(dst->connection, src->connection);
241 
242   MS_COPYSTELEM(connectiontype);
243 
244   /* TODO: need to handle joininfo (probably should be just set to NULL) */
245   dst->joininfo = NULL;
246 
247   return MS_SUCCESS;
248 }
249 
250 /***********************************************************************
251  * msCopyQueryMap()                                                    *
252  *                                                                     *
253  * Copy a queryMapObj, using msCopyColor()                             *
254  **********************************************************************/
255 
msCopyQueryMap(queryMapObj * dst,queryMapObj * src)256 int msCopyQueryMap(queryMapObj *dst, queryMapObj *src)
257 {
258   MS_COPYSTELEM(height);
259   MS_COPYSTELEM(width);
260   MS_COPYSTELEM(status);
261   MS_COPYSTELEM(style);
262   MS_COPYCOLOR(&(dst->color), &(src->color));
263 
264   return MS_SUCCESS;
265 }
266 
267 
268 /***********************************************************************
269  * msCopyLeader()                                                      *
270  *                                                                     *
271  * Copy a labelLeaderObj, using msCopyStyle()                          *
272  **********************************************************************/
273 
msCopyLabelLeader(labelLeaderObj * dst,labelLeaderObj * src)274 int msCopyLabelLeader(labelLeaderObj *dst, labelLeaderObj *src)
275 {
276   int i;
277   assert(dst && src);
278   MS_COPYSTELEM(gridstep);
279   MS_COPYSTELEM(maxdistance);
280   /*
281    ** now the styles
282    */
283 
284   /* free any previous styles on the dst label */
285   for(i=0; i<dst->numstyles; i++) { /* each style */
286     if (dst->styles[i]!=NULL) {
287       if( freeStyle(dst->styles[i]) == MS_SUCCESS ) msFree(dst->styles[i]);
288     }
289   }
290   dst->numstyles = 0;
291 
292   for (i = 0; i < src->numstyles; i++) {
293     if (msGrowLeaderStyles(dst) == NULL)
294       return MS_FAILURE;
295     if (initStyle(dst->styles[i]) != MS_SUCCESS) {
296       msSetError(MS_MEMERR, "Failed to init style.", "msCopyLabel()");
297       return MS_FAILURE;
298     }
299     if (msCopyStyle(dst->styles[i], src->styles[i]) != MS_SUCCESS) {
300       msSetError(MS_MEMERR, "Failed to copy style.", "msCopyLabel()");
301       return MS_FAILURE;
302     }
303     dst->numstyles++;
304   }
305   return MS_SUCCESS;
306 }
307 
308 /***********************************************************************
309  * msCopyLabel()                                                       *
310  *                                                                     *
311  * Copy a labelObj, using msCopyColor() and msCopyStyle()              *
312  **********************************************************************/
313 
msCopyLabel(labelObj * dst,labelObj * src)314 int msCopyLabel(labelObj *dst, labelObj *src)
315 {
316   int i;
317 
318   for(i=0; i<MS_LABEL_BINDING_LENGTH; i++) {
319     MS_COPYSTRING(dst->bindings[i].item, src->bindings[i].item);
320     dst->bindings[i].index = src->bindings[i].index; /* no way to use the macros */
321     MS_COPYSTRING(dst->exprBindings[i].string, src->exprBindings[i].string);
322     dst->exprBindings[i].type = src->exprBindings[i].type;
323   }
324   MS_COPYSTELEM(numbindings);
325   MS_COPYSTELEM(nexprbindings);
326 
327   MS_COPYSTRING(dst->font, src->font);
328 
329   MS_COPYCOLOR(&(dst->color), &(src->color));
330   MS_COPYCOLOR(&(dst->outlinecolor), &(src->outlinecolor));
331   MS_COPYCOLOR(&(dst->shadowcolor), &(src->shadowcolor));
332 
333   MS_COPYSTELEM(shadowsizex);
334   MS_COPYSTELEM(shadowsizey);
335 
336   MS_COPYSTELEM(size);
337   MS_COPYSTELEM(minsize);
338   MS_COPYSTELEM(maxsize);
339   MS_COPYSTELEM(position);
340   MS_COPYSTELEM(offsetx);
341   MS_COPYSTELEM(offsety);
342   MS_COPYSTELEM(angle);
343   MS_COPYSTELEM(anglemode);
344   MS_COPYSTELEM(buffer);
345   MS_COPYSTELEM(wrap);
346   MS_COPYSTELEM(align);
347   MS_COPYSTELEM(maxlength);
348   MS_COPYSTELEM(minfeaturesize);
349 
350   MS_COPYSTELEM(minscaledenom);
351   MS_COPYSTELEM(maxscaledenom);
352 
353   MS_COPYSTELEM(autominfeaturesize);
354 
355   MS_COPYSTELEM(mindistance);
356   MS_COPYSTELEM(partials);
357   MS_COPYSTELEM(force);
358   MS_COPYSTELEM(priority);
359 
360   MS_COPYSTELEM(repeatdistance);
361   MS_COPYSTELEM(maxoverlapangle);
362 
363 
364   MS_COPYSTRING(dst->encoding, src->encoding);
365 
366   MS_COPYSTELEM(outlinewidth);
367   MS_COPYSTELEM(space_size_10);
368 
369   if (msCopyExpression(&(dst->expression), &(src->expression)) != MS_SUCCESS) {
370     msSetError(MS_MEMERR, "Failed to copy expression.", "msCopyLabel()");
371     return MS_FAILURE;
372   }
373 
374   if (msCopyExpression(&(dst->text), &(src->text)) != MS_SUCCESS) {
375     msSetError(MS_MEMERR, "Failed to copy text.", "msCopyLabel()");
376     return MS_FAILURE;
377   }
378 
379   /*
380   ** now the styles
381   */
382 
383   /* free any previous styles on the dst label */
384   for(i=0; i<dst->numstyles; i++) { /* each style */
385     if (dst->styles[i]!=NULL) {
386       if( freeStyle(dst->styles[i]) == MS_SUCCESS ) msFree(dst->styles[i]);
387     }
388   }
389   dst->numstyles = 0;
390 
391   for (i = 0; i < src->numstyles; i++) {
392     if (msGrowLabelStyles(dst) == NULL)
393       return MS_FAILURE;
394     if (initStyle(dst->styles[i]) != MS_SUCCESS) {
395       msSetError(MS_MEMERR, "Failed to init style.", "msCopyLabel()");
396       return MS_FAILURE;
397     }
398     if (msCopyStyle(dst->styles[i], src->styles[i]) != MS_SUCCESS) {
399       msSetError(MS_MEMERR, "Failed to copy style.", "msCopyLabel()");
400       return MS_FAILURE;
401     }
402     dst->numstyles++;
403   }
404 
405   if(src->leader) {
406     dst->leader = msSmallMalloc(sizeof(labelLeaderObj));
407     initLeader(dst->leader);
408     msCopyLabelLeader(dst->leader,src->leader);
409   } else {
410     if(dst->leader) {
411       freeLabelLeader(dst->leader);
412       msFree(dst->leader);
413     }
414     dst->leader = NULL;
415   }
416 
417   return MS_SUCCESS;
418 }
419 
420 /***********************************************************************
421  * msCopyWeb()                                                         *
422  *                                                                     *
423  * Copy webObj, using msCopyRect(), msCreateHashTable(), and           *
424  * msCopyHashTable()                                                   *
425  **********************************************************************/
426 
msCopyWeb(webObj * dst,webObj * src,mapObj * map)427 int msCopyWeb(webObj *dst, webObj *src, mapObj *map)
428 {
429 
430   MS_COPYSTRING(dst->log, src->log);
431   MS_COPYSTRING(dst->imagepath, src->imagepath);
432   MS_COPYSTRING(dst->imageurl, src->imageurl);
433   dst->map = map;
434 #ifndef __cplusplus
435   MS_COPYSTRING(dst->template, src->template);
436 #else
437   MS_COPYSTRING(dst->_template, src->_template);
438 #endif
439   MS_COPYSTRING(dst->header, src->header);
440   MS_COPYSTRING(dst->footer, src->footer);
441   MS_COPYSTRING(dst->empty, src->empty);
442   MS_COPYSTRING(dst->error, src->error);
443 
444   MS_COPYRECT(&(dst->extent), &(src->extent));
445 
446   MS_COPYSTELEM(minscaledenom);
447   MS_COPYSTELEM(maxscaledenom);
448   MS_COPYSTRING(dst->mintemplate, src->mintemplate);
449   MS_COPYSTRING(dst->maxtemplate, src->maxtemplate);
450 
451   if (&(src->metadata)) {
452     /* dst->metadata = msCreateHashTable(); */
453     if (msCopyHashTable(&(dst->metadata), &(src->metadata)) != MS_SUCCESS)
454       return MS_FAILURE;
455   }
456   msCopyHashTable(&dst->validation,&src->validation);
457 
458   MS_COPYSTRING(dst->queryformat, src->queryformat);
459   MS_COPYSTRING(dst->legendformat, src->legendformat);
460   MS_COPYSTRING(dst->browseformat, src->browseformat);
461 
462   return MS_SUCCESS ;
463 }
464 
465 /***********************************************************************
466  * msCopyStyle()                                                       *
467  *                                                                     *
468  * Copy a styleObj, using msCopyColor()                                *
469  **********************************************************************/
470 
msCopyStyle(styleObj * dst,styleObj * src)471 int msCopyStyle(styleObj *dst, styleObj *src)
472 {
473   int i;
474 
475   for(i=0; i<MS_STYLE_BINDING_LENGTH; i++) {
476     MS_COPYSTRING(dst->bindings[i].item, src->bindings[i].item);
477     dst->bindings[i].index = src->bindings[i].index; /* no way to use the macros */
478     MS_COPYSTRING(dst->exprBindings[i].string, src->exprBindings[i].string);
479     dst->exprBindings[i].type = src->exprBindings[i].type;
480   }
481   MS_COPYSTELEM(numbindings);
482   MS_COPYSTELEM(nexprbindings);
483 
484   MS_COPYCOLOR(&(dst->color), &(src->color));
485   MS_COPYCOLOR(&(dst->outlinecolor),&(src->outlinecolor));
486   MS_COPYCOLOR(&(dst->backgroundcolor), &(src->backgroundcolor));
487 
488   MS_COPYCOLOR(&(dst->mincolor), &(src->mincolor));
489   MS_COPYCOLOR(&(dst->maxcolor), &(src->maxcolor));
490 
491   MS_COPYSTRING(dst->symbolname, src->symbolname);
492   MS_COPYSTELEM(patternlength);
493   for(i=0; i<src->patternlength; i++)
494     dst->pattern[i]=src->pattern[i];
495   MS_COPYSTELEM(initialgap);
496   MS_COPYSTELEM(gap);
497   MS_COPYSTELEM(linejoin);
498   MS_COPYSTELEM(linejoinmaxsize);
499   MS_COPYSTELEM(linecap);
500   MS_COPYSTELEM(symbol);
501   MS_COPYSTELEM(size);
502   MS_COPYSTELEM(minsize);
503   MS_COPYSTELEM(maxsize);
504   MS_COPYSTELEM(width);
505   MS_COPYSTELEM(minwidth);
506   MS_COPYSTELEM(maxwidth);
507   MS_COPYSTELEM(offsetx);
508   MS_COPYSTELEM(offsety);
509   MS_COPYSTELEM(angle);
510   MS_COPYSTELEM(autoangle);
511   MS_COPYSTELEM(minvalue);
512   MS_COPYSTELEM(maxvalue);
513   MS_COPYSTELEM(opacity);
514   MS_COPYSTRING(dst->_geomtransform.string, src->_geomtransform.string);
515   MS_COPYSTELEM(_geomtransform.type);
516   MS_COPYSTRING(dst->rangeitem, src->rangeitem);
517   MS_COPYSTELEM(rangeitemindex);
518   MS_COPYSTELEM(outlinewidth);
519   MS_COPYSTELEM(minscaledenom);
520   MS_COPYSTELEM(maxscaledenom);
521   /* TODO: add copy for bindings */
522 
523   return MS_SUCCESS;
524 }
525 
526 /***********************************************************************
527  * msCopyClass()                                                       *
528  *                                                                     *
529  * Copy a classObj, using msCopyExpression(), msCopyStyle(),           *
530  * msCopyLabel(), msCreateHashTable(), msCopyHashTable()               *
531  **********************************************************************/
532 
msCopyClass(classObj * dst,classObj * src,layerObj * layer)533 int msCopyClass(classObj *dst, classObj *src, layerObj *layer)
534 {
535   int i, return_value;
536 
537   return_value = msCopyExpression(&(dst->expression),&(src->expression));
538   if (return_value != MS_SUCCESS) {
539     msSetError(MS_MEMERR, "Failed to copy expression.", "msCopyClass()");
540     return MS_FAILURE;
541   }
542 
543   MS_COPYSTELEM(status);
544   MS_COPYSTELEM(isfallback);
545 
546   /* free any previous styles on the dst layer */
547   for(i=0; i<dst->numstyles; i++) { /* each style */
548     if (dst->styles[i]!=NULL) {
549       if( freeStyle(dst->styles[i]) == MS_SUCCESS ) {
550         msFree(dst->styles[i]);
551       }
552     }
553   }
554   dst->numstyles = 0;
555 
556   for (i = 0; i < src->numstyles; i++) {
557     if (msGrowClassStyles(dst) == NULL)
558       return MS_FAILURE;
559     if (initStyle(dst->styles[i]) != MS_SUCCESS) {
560       msSetError(MS_MEMERR, "Failed to init style.", "msCopyClass()");
561       return MS_FAILURE;
562     }
563     if (msCopyStyle(dst->styles[i], src->styles[i]) != MS_SUCCESS) {
564       msSetError(MS_MEMERR, "Failed to copy style.", "msCopyClass()");
565       return MS_FAILURE;
566     }
567 
568     dst->numstyles++;
569   }
570 
571   for (i=0; i<src->numlabels; i++) {
572     if (msGrowClassLabels(dst) == NULL)
573       return MS_FAILURE;
574     initLabel(dst->labels[i]);
575     if (msCopyLabel(dst->labels[i], src->labels[i]) != MS_SUCCESS) {
576       msSetError(MS_MEMERR, "Failed to copy label.", "msCopyClass()");
577       return MS_FAILURE;
578     }
579 
580     dst->numlabels++;
581   }
582   MS_COPYSTELEM(numlabels);
583 
584   if(src->leader) {
585     if(dst->leader) {
586       freeLabelLeader(dst->leader);
587     }
588     if(!dst->leader) {
589       dst->leader = msSmallMalloc(sizeof(labelLeaderObj));
590       initLeader(dst->leader);
591     }
592     msCopyLabelLeader(dst->leader,src->leader);
593   }
594 
595   MS_COPYSTRING(dst->keyimage, src->keyimage);
596   MS_COPYSTRING(dst->name, src->name);
597   MS_COPYSTRING(dst->title, src->title);
598   MS_COPYSTRING(dst->group, src->group);
599 
600   if (msCopyExpression(&(dst->text), &(src->text)) != MS_SUCCESS) {
601     msSetError(MS_MEMERR, "Failed to copy text.", "msCopyClass()");
602     return MS_FAILURE;
603   }
604 
605 #ifndef __cplusplus
606   MS_COPYSTRING(dst->template, src->template);
607 #else
608   MS_COPYSTRING(dst->_template, src->_template);
609 #endif
610 
611   if (&(src->metadata) != NULL) {
612     /* dst->metadata = msCreateHashTable(); */
613     msCopyHashTable(&(dst->metadata), &(src->metadata));
614   }
615   msCopyHashTable(&dst->validation,&src->validation);
616 
617   MS_COPYSTELEM(minscaledenom);
618   MS_COPYSTELEM(maxscaledenom);
619   MS_COPYSTELEM(layer);
620   MS_COPYSTELEM(debug);
621 
622   return MS_SUCCESS;
623 }
624 
msCopyCluster(clusterObj * dst,clusterObj * src)625 int msCopyCluster(clusterObj *dst, clusterObj *src)
626 {
627   int return_value;
628 
629   MS_COPYSTELEM(maxdistance);
630   MS_COPYSTELEM(buffer);
631   MS_COPYSTRING(dst->region, src->region);
632 
633   return_value = msCopyExpression(&(dst->group),&(src->group));
634   if (return_value != MS_SUCCESS) {
635     msSetError(MS_MEMERR, "Failed to copy cluster group.", "msCopyCluster()");
636     return MS_FAILURE;
637   }
638 
639   return_value = msCopyExpression(&(dst->filter),&(src->filter));
640   if (return_value != MS_SUCCESS) {
641     msSetError(MS_MEMERR, "Failed to copy cluster filter.", "msCopyCluster()");
642     return MS_FAILURE;
643   }
644 
645   return MS_SUCCESS;
646 }
647 
648 /***********************************************************************
649  * msCopyGrid()                                                        *
650  **********************************************************************/
651 
msCopyGrid(graticuleObj * dst,graticuleObj * src)652 int msCopyGrid(graticuleObj *dst, graticuleObj *src)
653 {
654   MS_COPYSTELEM(dwhichlatitude);
655   MS_COPYSTELEM(dwhichlongitude);
656   MS_COPYSTELEM(dstartlatitude);
657   MS_COPYSTELEM(dstartlongitude);
658   MS_COPYSTELEM(dendlatitude);
659   MS_COPYSTELEM(dendlongitude);
660   MS_COPYSTELEM(dincrementlatitude);
661   MS_COPYSTELEM(dincrementlongitude);
662   MS_COPYSTELEM(minarcs);
663   MS_COPYSTELEM(maxarcs);
664   MS_COPYSTELEM(minincrement);
665   MS_COPYSTELEM(maxincrement);
666   MS_COPYSTELEM(minsubdivides);
667   MS_COPYSTELEM(maxsubdivides);
668   MS_COPYSTELEM(bvertical);
669   MS_COPYSTELEM(blabelaxes);
670   MS_COPYSTELEM(ilabelstate);
671   MS_COPYSTELEM(ilabeltype);
672   MS_COPYRECT(&(dst->extent), &(src->extent));
673   MS_COPYSTRING(dst->labelformat, src->labelformat);
674 
675   return MS_SUCCESS;
676 }
677 
678 #ifdef why_on_earth_would_you_copy_a_labelcache
679 
680 /***********************************************************************
681  * msCopyLabelCacheMember()                                            *
682  *                                                                     *
683  * Copy a labelCacheMemberObj using msCopyStyle(), msCopyPoint()       *
684  *                                                                     *
685  * Note: since it seems most users will want to clone maps rather than *
686  * make exact copies, this method might not get much use.              *
687  **********************************************************************/
688 
msCopyLabelCacheMember(labelCacheMemberObj * dst,labelCacheMemberObj * src)689 int msCopyLabelCacheMember(labelCacheMemberObj *dst, labelCacheMemberObj *src)
690 {
691   int i;
692 
693   MS_COPYSTELEM(featuresize);
694 
695   MS_COPYSTELEM(numstyles);
696   for (i = 0; i < dst->numstyles; i++) {
697     msCopyStyle(&(dst->styles[i]), &(src->styles[i]));
698   }
699 
700   MS_COPYSTELEM(numlabels);
701   dst->labels = (labelObj *) msSmallMalloc(sizeof(labelObj)*dst->numlabels);
702   for (i = 0; i < dst->numlabels; i++) {
703     msCopyLabel(&(dst->labels[i]), &(src->labels[i]));
704   }
705 
706   MS_COPYSTELEM(layerindex);
707   MS_COPYSTELEM(classindex);
708   MS_COPYSTELEM(tileindex);
709   MS_COPYSTELEM(shapeindex);
710   MS_COPYPOINT(&(dst->point), &(src->point));
711   /* msCopyShape(&(dst->poly), &(src->poly)); */
712   MS_COPYSTELEM(status);
713 
714   return MS_SUCCESS;
715 }
716 
717 /***********************************************************************
718  * msCopyMarkerCacheMember()                                           *
719  *                                                                     *
720  * Copy a markerCacheMemberObj                                         *
721  **********************************************************************/
722 
msCopyMarkerCacheMember(markerCacheMemberObj * dst,markerCacheMemberObj * src)723 int msCopyMarkerCacheMember(markerCacheMemberObj *dst,
724                             markerCacheMemberObj *src)
725 {
726   MS_COPYSTELEM(id);
727 
728   /* msCopyShape(&(dst->poly), &(src->poly)); */
729   return MS_SUCCESS;
730 }
731 
732 /***********************************************************************
733  * msCopyLabelCacheSlot()                                                  *
734  **********************************************************************/
735 
msCopyLabelCacheSlot(labelCacheSlotObj * dst,labelCacheSlotObj * src)736 int msCopyLabelCacheSlot(labelCacheSlotObj *dst, labelCacheSlotObj *src)
737 {
738   int i;
739 
740   for (i = 0; i < dst->numlabels; i++) {
741     msCopyLabelCacheMember(&(dst->labels[i]), &(src->labels[i]));
742   }
743   MS_COPYSTELEM(cachesize);
744   MS_COPYSTELEM(nummarkers);
745   for (i = 0; i < dst->nummarkers; i++) {
746     msCopyMarkerCacheMember(&(dst->markers[i]), &(src->markers[i]));
747   }
748   MS_COPYSTELEM(markercachesize);
749 
750   return MS_SUCCESS;
751 }
752 
753 /***********************************************************************
754  * msCopyLabelCache()                                                  *
755  **********************************************************************/
756 
msCopyLabelCache(labelCacheObj * dst,labelCacheObj * src)757 int msCopyLabelCache(labelCacheObj *dst, labelCacheObj *src)
758 {
759   int p;
760   MS_COPYSTELEM(numlabels);
761 
762   for (p=0; p<MS_MAX_LABEL_PRIORITY; p++) {
763     msCopyLabelCacheSlot(&(dst->slots[p]), &(src->slots[p]));
764   }
765 
766   return MS_SUCCESS;
767 }
768 
769 #endif
770 
771 /***********************************************************************
772  * msCopyResult()                                                      *
773  **********************************************************************/
774 
msCopyResult(resultObj * dst,resultObj * src)775 int msCopyResult(resultObj *dst, resultObj *src)
776 {
777   MS_COPYSTELEM(shapeindex);
778   MS_COPYSTELEM(tileindex);
779   MS_COPYSTELEM(classindex);
780   MS_COPYSTELEM(resultindex);
781 
782   return MS_SUCCESS;
783 }
784 
785 /***********************************************************************
786  * msCopyResultCache()                                                 *
787  **********************************************************************/
788 
msCopyResultCache(resultCacheObj * dst,resultCacheObj * src)789 int msCopyResultCache(resultCacheObj *dst, resultCacheObj *src)
790 {
791   int i;
792   MS_COPYSTELEM(cachesize);
793   MS_COPYSTELEM(numresults);
794   for (i = 0; i < dst->numresults; i++) {
795     msCopyResult(&(dst->results[i]), &(src->results[i]));
796   }
797   MS_COPYRECT(&(dst->bounds), &(src->bounds));
798 
799   return MS_SUCCESS;
800 }
801 
802 /***********************************************************************
803  * msCopyReferenceMap()                                                *
804  *                                                                     *
805  * Copy a referenceMapObj using mapfile.c:initReferenceMap(),          *
806  * msCopyRect(), msCopyColor()                                         *
807  **********************************************************************/
808 
msCopyReferenceMap(referenceMapObj * dst,referenceMapObj * src,mapObj * map)809 int msCopyReferenceMap(referenceMapObj *dst, referenceMapObj *src,
810                        mapObj *map)
811 {
812 
813   initReferenceMap(dst);
814 
815   MS_COPYRECT(&(dst->extent), &(src->extent));
816 
817   MS_COPYSTELEM(height);
818   MS_COPYSTELEM(width);
819 
820 
821   MS_COPYCOLOR(&(dst->color), &(src->color));
822   MS_COPYCOLOR(&(dst->outlinecolor),&(src->outlinecolor));
823   MS_COPYSTRING(dst->image, src->image);
824 
825   MS_COPYSTELEM(status);
826   MS_COPYSTELEM(marker);
827   MS_COPYSTRING(dst->markername, src->markername);
828   MS_COPYSTELEM(markersize);
829   MS_COPYSTELEM(minboxsize);
830   MS_COPYSTELEM(maxboxsize);
831   dst->map = map;
832 
833   return MS_SUCCESS;
834 }
835 
836 /***********************************************************************
837  * msCopyScalebar()                                                    *
838  *                                                                     *
839  * Copy a scalebarObj, using initScalebar(), msCopyColor(),            *
840  * and msCopyLabel()                                                   *
841  **********************************************************************/
842 
msCopyScalebar(scalebarObj * dst,scalebarObj * src)843 int msCopyScalebar(scalebarObj *dst, scalebarObj *src)
844 {
845 
846   initScalebar(dst);
847 
848   MS_COPYCOLOR(&(dst->imagecolor), &(src->imagecolor));
849   MS_COPYSTELEM(height);
850   MS_COPYSTELEM(width);
851   MS_COPYSTELEM(style);
852   MS_COPYSTELEM(intervals);
853 
854   if (msCopyLabel(&(dst->label), &(src->label)) != MS_SUCCESS) {
855     msSetError(MS_MEMERR, "Failed to copy label.","msCopyScalebar()");
856     return MS_FAILURE;
857   }
858 
859   MS_COPYCOLOR(&(dst->color), &(src->color));
860   MS_COPYCOLOR(&(dst->backgroundcolor), &(src->backgroundcolor));
861 
862   MS_COPYCOLOR(&(dst->outlinecolor), &(src->outlinecolor));
863 
864   MS_COPYSTELEM(units);
865   MS_COPYSTELEM(status);
866   MS_COPYSTELEM(position);
867   MS_COPYSTELEM(transparent);
868   MS_COPYSTELEM(interlace);
869   MS_COPYSTELEM(postlabelcache);
870   MS_COPYSTELEM(align);
871 
872   return MS_SUCCESS;
873 }
874 
875 /***********************************************************************
876  * msCopyLegend()                                                      *
877  *                                                                     *
878  * Copy a legendObj, using msCopyColor()                               *
879  **********************************************************************/
880 
msCopyLegend(legendObj * dst,legendObj * src,mapObj * map)881 int msCopyLegend(legendObj *dst, legendObj *src, mapObj *map)
882 {
883   int return_value;
884 
885   MS_COPYCOLOR(&(dst->imagecolor), &(src->imagecolor));
886 
887   return_value = msCopyLabel(&(dst->label), &(src->label));
888   if (return_value != MS_SUCCESS) {
889     msSetError(MS_MEMERR, "Failed to copy label.",
890                "msCopyLegend()");
891     return MS_FAILURE;
892   }
893 
894   MS_COPYSTELEM(keysizex);
895   MS_COPYSTELEM(keysizey);
896   MS_COPYSTELEM(keyspacingx);
897   MS_COPYSTELEM(keyspacingy);
898 
899   MS_COPYCOLOR(&(dst->outlinecolor),&(src->outlinecolor));
900 
901   MS_COPYSTELEM(status);
902   MS_COPYSTELEM(height);
903   MS_COPYSTELEM(width);
904   MS_COPYSTELEM(position);
905   MS_COPYSTELEM(transparent);
906   MS_COPYSTELEM(interlace);
907   MS_COPYSTELEM(postlabelcache);
908 
909 #ifndef __cplusplus
910   MS_COPYSTRING(dst->template, src->template);
911 #else
912   MS_COPYSTRING(dst->_template, src->_template);
913 #endif
914   dst->map = map;
915 
916   return MS_SUCCESS;
917 }
918 
msCopyScaleTokenEntry(scaleTokenEntryObj * src,scaleTokenEntryObj * dst)919 int msCopyScaleTokenEntry(scaleTokenEntryObj *src, scaleTokenEntryObj *dst) {
920   MS_COPYSTRING(dst->value,src->value);
921   MS_COPYSTELEM(minscale);
922   MS_COPYSTELEM(maxscale);
923   return MS_SUCCESS;
924 }
925 
msCopyScaleToken(scaleTokenObj * src,scaleTokenObj * dst)926 int msCopyScaleToken(scaleTokenObj *src, scaleTokenObj *dst) {
927   int i;
928   MS_COPYSTRING(dst->name,src->name);
929   MS_COPYSTELEM(n_entries);
930   dst->tokens = (scaleTokenEntryObj*)msSmallCalloc(src->n_entries,sizeof(scaleTokenEntryObj));
931   for(i=0;i<src->n_entries;i++) {
932     msCopyScaleTokenEntry(&src->tokens[i],&dst->tokens[i]);
933   }
934   return MS_SUCCESS;
935 }
936 
msCopyCompositingFilter(CompositingFilter ** pdst,CompositingFilter * src)937 int msCopyCompositingFilter(CompositingFilter **pdst, CompositingFilter *src) {
938   CompositingFilter *dst = NULL;
939   if(!src) {
940     *pdst = NULL;
941     return MS_SUCCESS;
942   }
943   while(src) {
944     if(!dst) {
945       dst = *pdst = msSmallMalloc(sizeof(CompositingFilter));
946     } else {
947       dst->next = msSmallMalloc(sizeof(CompositingFilter));
948       dst = dst->next;
949     }
950     dst->filter = msStrdup(src->filter);
951     dst->next = NULL;
952     src = src->next;
953   }
954   return MS_SUCCESS;
955 }
956 
msCopyCompositer(LayerCompositer ** ldst,LayerCompositer * src)957 int msCopyCompositer(LayerCompositer **ldst, LayerCompositer *src) {
958   LayerCompositer *dst = NULL;
959   if(!src) {
960     *ldst = NULL;
961     return MS_SUCCESS;
962   }
963 
964   while(src) {
965     if(!dst) {
966       dst = *ldst = msSmallMalloc(sizeof(LayerCompositer));
967     } else {
968       dst->next = msSmallMalloc(sizeof(LayerCompositer));
969       dst = dst->next;
970     }
971     dst->comp_op = src->comp_op;
972     dst->opacity = src->opacity;
973     dst->next = NULL;
974     msCopyCompositingFilter(&dst->filter, src->filter);
975     src = src->next;
976   }
977   return MS_SUCCESS;
978 }
979 
980 /***********************************************************************
981  * msCopyLayer()                                                       *
982  *                                                                     *
983  * Copy a layerObj, using mapfile.c:initClass(), msCopyClass(),        *
984  * msCopyColor(), msCopyProjection(), msShapefileOpen(),                 *
985  * msCreateHashTable(), msCopyHashTable(), msCopyExpression()          *
986  *                                                                     *
987  * As it stands, we are not copying a layer's resultcache              *
988  **********************************************************************/
989 
msCopyLayer(layerObj * dst,layerObj * src)990 int msCopyLayer(layerObj *dst, layerObj *src)
991 {
992   int i, return_value;
993   featureListNodeObjPtr current;
994 
995   MS_COPYSTELEM(index);
996   MS_COPYSTRING(dst->classitem, src->classitem);
997 
998   MS_COPYSTELEM(classitemindex);
999 
1000   for(i = 0; i < src->numscaletokens; i++) {
1001     if(msGrowLayerScaletokens(dst) == NULL)
1002       return MS_FAILURE;
1003     initScaleToken(&dst->scaletokens[i]);
1004     msCopyScaleToken(&src->scaletokens[i],&dst->scaletokens[i]);
1005     dst->numscaletokens++;
1006   }
1007 
1008   for (i = 0; i < src->numclasses; i++) {
1009     if (msGrowLayerClasses(dst) == NULL)
1010       return MS_FAILURE;
1011 #ifndef __cplusplus
1012     initClass(dst->class[i]);
1013     return_value = msCopyClass(dst->class[i], src->class[i], dst);
1014 #else
1015     initClass(dst->_class[i]);
1016     return_value = msCopyClass(dst->_class[i], src->_class[i], dst);
1017 #endif
1018     if (return_value != MS_SUCCESS) {
1019       msSetError(MS_MEMERR, "Failed to copy class.", "msCopyLayer()");
1020       return MS_FAILURE;
1021     }
1022     dst->numclasses++;
1023   }
1024   MS_COPYSTRING(dst->header, src->header);
1025   MS_COPYSTRING(dst->footer, src->footer);
1026 #ifndef __cplusplus
1027   MS_COPYSTRING(dst->template, src->template);
1028 #else
1029   MS_COPYSTRING(dst->_template, src->_template);
1030 #endif
1031 
1032   MS_COPYSTRING(dst->name, src->name);
1033   MS_COPYSTRING(dst->group, src->group);
1034   MS_COPYSTRING(dst->data, src->data);
1035   MS_COPYSTRING(dst->encoding, src->encoding);
1036 
1037   MS_COPYSTELEM(rendermode);
1038   MS_COPYSTELEM(status);
1039   MS_COPYSTELEM(type);
1040   MS_COPYSTELEM(tolerance);
1041   MS_COPYSTELEM(toleranceunits);
1042   MS_COPYSTELEM(symbolscaledenom);
1043   MS_COPYSTELEM(scalefactor);
1044   MS_COPYSTELEM(minscaledenom);
1045   MS_COPYSTELEM(maxscaledenom);
1046 
1047   MS_COPYSTELEM(labelminscaledenom);
1048   MS_COPYSTELEM(labelmaxscaledenom);
1049   MS_COPYSTELEM(mingeowidth);
1050   MS_COPYSTELEM(maxgeowidth);
1051 
1052   MS_COPYSTELEM(sizeunits);
1053   MS_COPYSTELEM(maxfeatures);
1054 
1055   MS_COPYCOLOR(&(dst->offsite), &(src->offsite));
1056 
1057   MS_COPYSTELEM(transform);
1058   MS_COPYSTELEM(labelcache);
1059   MS_COPYSTELEM(postlabelcache);
1060 
1061   MS_COPYSTRING(dst->labelitem, src->labelitem);
1062   MS_COPYSTELEM(labelitemindex);
1063 
1064   MS_COPYSTRING(dst->tileitem, src->tileitem);
1065   MS_COPYSTELEM(tileitemindex);
1066 
1067   MS_COPYSTRING(dst->tilesrs, src->tilesrs);
1068 
1069   MS_COPYSTRING(dst->tileindex, src->tileindex);
1070 
1071   return_value = msCopyProjection(&(dst->projection),&(src->projection));
1072   if (return_value != MS_SUCCESS) {
1073     msSetError(MS_MEMERR, "Failed to copy projection.", "msCopyLayer()");
1074     return MS_FAILURE;
1075   }
1076 
1077   return_value = msCopyCluster(&(dst->cluster),&(src->cluster));
1078   if (return_value != MS_SUCCESS) {
1079     return MS_FAILURE;
1080   }
1081 
1082   MS_COPYSTELEM(project);
1083   MS_COPYSTELEM(units);
1084 
1085   current = src->features;
1086   while(current != NULL) {
1087     insertFeatureList(&(dst->features), &(current->shape));
1088     current = current->next;
1089   }
1090 
1091   MS_COPYSTRING(dst->connection, src->connection);
1092   MS_COPYSTELEM(connectiontype);
1093 
1094   MS_COPYSTRING(dst->plugin_library, src->plugin_library);
1095   MS_COPYSTRING(dst->plugin_library_original, src->plugin_library_original);
1096 
1097   /* Do not copy *layerinfo, items, or iteminfo. these are all initialized
1098      when the copied layer is opened */
1099 
1100   return_value = msCopyExpression(&(dst->filter), &(src->filter));
1101   if (return_value != MS_SUCCESS) {
1102     msSetError(MS_MEMERR, "Failed to copy filter.", "msCopyLayer()");
1103     return MS_FAILURE;
1104   }
1105 
1106   MS_COPYSTRING(dst->filteritem, src->filteritem);
1107   MS_COPYSTELEM(filteritemindex);
1108 
1109   MS_COPYSTRING(dst->styleitem, src->styleitem);
1110   MS_COPYSTELEM(styleitemindex);
1111 
1112   MS_COPYSTRING(dst->requires, src->requires);
1113   MS_COPYSTRING(dst->labelrequires, src->labelrequires);
1114 
1115   if (&(src->metadata)) {
1116     msCopyHashTable(&(dst->metadata), &(src->metadata));
1117   }
1118   msCopyHashTable(&dst->validation,&src->validation);
1119 
1120   MS_COPYSTELEM(dump);
1121   MS_COPYSTELEM(debug);
1122 
1123   /* No need to copy the numprocessing member, as it is incremented by
1124      msLayerAddProcessing */
1125   for (i = 0; i < src->numprocessing; i++) {
1126     msLayerAddProcessing(dst, msLayerGetProcessing(src, i));
1127   }
1128 
1129   MS_COPYSTELEM(numjoins);
1130 
1131   for (i = 0; i < dst->numjoins; i++) {
1132     initJoin(&(dst->joins[i]));
1133     return_value = msCopyJoin(&(dst->joins[i]), &(src->joins[i]));
1134     if (return_value != MS_SUCCESS)
1135       return MS_FAILURE;
1136   }
1137 
1138   MS_COPYRECT(&(dst->extent), &(src->extent));
1139 
1140   MS_COPYSTRING(dst->classgroup, src->classgroup);
1141   MS_COPYSTRING(dst->mask, src->mask);
1142 
1143   if (src->grid) {
1144     if (dst->grid) {
1145       freeGrid(dst->grid);
1146       msFree(dst->grid);
1147     }
1148     dst->grid = (void *) malloc(sizeof(graticuleObj));
1149     MS_CHECK_ALLOC(dst->grid, sizeof(graticuleObj), -1);
1150     initGrid(dst->grid);
1151     msCopyGrid(dst->grid, src->grid);
1152   }
1153 
1154   if(src->compositer) {
1155     msCopyCompositer(&dst->compositer, src->compositer);
1156   }
1157 
1158   return MS_SUCCESS;
1159 }
1160 
1161 /***********************************************************************
1162  * msCopyMap()                                                         *
1163  *                                                                     *
1164  * Copy a mapObj, using mapfile.c:initLayer(), msCopyLayer(),          *
1165 
1166  * msCopyLegend(), msCopyScalebar(), msCopyProjection()                *
1167  * msCopyOutputFormat(), msCopyWeb(), msCopyReferenceMap()             *
1168  **********************************************************************/
1169 
msCopyMap(mapObj * dst,mapObj * src)1170 int msCopyMap(mapObj *dst, mapObj *src)
1171 {
1172   int i, return_value;
1173   outputFormatObj *format;
1174 
1175   MS_COPYSTRING(dst->name, src->name);
1176   MS_COPYSTELEM(status);
1177   MS_COPYSTELEM(height);
1178   MS_COPYSTELEM(width);
1179   MS_COPYSTELEM(maxsize);
1180 
1181   for (i = 0; i < src->numlayers; i++) {
1182     if (msGrowMapLayers(dst) == NULL)
1183       return MS_FAILURE;
1184     initLayer((GET_LAYER(dst, i)), dst);
1185 
1186     return_value = msCopyLayer((GET_LAYER(dst, i)), (GET_LAYER(src, i)));
1187     if (return_value != MS_SUCCESS) {
1188       msSetError(MS_MEMERR, "Failed to copy layer.", "msCopyMap()");
1189       return MS_FAILURE;
1190     }
1191     dst->numlayers++;
1192   }
1193 
1194   return_value = msCopyFontSet(&(dst->fontset), &(src->fontset), dst);
1195   if (return_value != MS_SUCCESS) {
1196     msSetError(MS_MEMERR, "Failed to copy fontset.", "msCopyMap()");
1197     return MS_FAILURE;
1198   }
1199 
1200   return_value = msCopySymbolSet(&(dst->symbolset), &(src->symbolset), dst);
1201   if(return_value != MS_SUCCESS) {
1202     msSetError(MS_MEMERR, "Failed to copy symbolset.", "msCopyMap()");
1203     return MS_FAILURE;
1204   }
1205 
1206   /* msCopyLabelCache(&(dst->labelcache), &(src->labelcache)); */
1207   MS_COPYSTELEM(transparent);
1208   MS_COPYSTELEM(interlace);
1209   MS_COPYSTELEM(imagequality);
1210 
1211   MS_COPYRECT(&(dst->extent), &(src->extent));
1212 
1213   MS_COPYSTELEM(cellsize);
1214   MS_COPYSTELEM(units);
1215   MS_COPYSTELEM(scaledenom);
1216   MS_COPYSTELEM(defresolution);
1217   MS_COPYSTELEM(resolution);
1218   MS_COPYSTRING(dst->shapepath, src->shapepath);
1219   MS_COPYSTRING(dst->mappath, src->mappath);
1220   MS_COPYSTELEM(sldurl);
1221 
1222   MS_COPYCOLOR(&(dst->imagecolor), &(src->imagecolor));
1223 
1224   /* clear existing destination format list */
1225   if( dst->outputformat && --dst->outputformat->refcount < 1 ) {
1226     msFreeOutputFormat( dst->outputformat );
1227     dst->outputformat = NULL;
1228   }
1229 
1230   for(i=0; i < dst->numoutputformats; i++ ) {
1231     if( --dst->outputformatlist[i]->refcount < 1 )
1232       msFreeOutputFormat( dst->outputformatlist[i] );
1233   }
1234   if( dst->outputformatlist != NULL )
1235     msFree( dst->outputformatlist );
1236   dst->outputformatlist = NULL;
1237   dst->outputformat = NULL;
1238   dst->numoutputformats = 0;
1239 
1240   for (i = 0; i < src->numoutputformats; i++)
1241     msAppendOutputFormat( dst,
1242                           msCloneOutputFormat( src->outputformatlist[i]) );
1243 
1244   /* set the active output format */
1245   MS_COPYSTRING(dst->imagetype, src->imagetype);
1246   format = msSelectOutputFormat( dst, dst->imagetype );
1247   msApplyOutputFormat(&(dst->outputformat), format, MS_NOOVERRIDE,
1248                       MS_NOOVERRIDE, MS_NOOVERRIDE );
1249 
1250   return_value = msCopyProjection(&(dst->projection),&(src->projection));
1251   if (return_value != MS_SUCCESS) {
1252     msSetError(MS_MEMERR, "Failed to copy projection.", "msCopyMap()");
1253     return MS_FAILURE;
1254   }
1255 
1256   /* No need to copy latlon projection */
1257 
1258   return_value = msCopyReferenceMap(&(dst->reference),&(src->reference),
1259                                     dst);
1260   if (return_value != MS_SUCCESS) {
1261     msSetError(MS_MEMERR, "Failed to copy reference.", "msCopyMap()");
1262     return MS_FAILURE;
1263   }
1264 
1265   return_value = msCopyScalebar(&(dst->scalebar), &(src->scalebar));
1266   if (return_value != MS_SUCCESS) {
1267     msSetError(MS_MEMERR, "Failed to copy scalebar.", "msCopyMap()");
1268     return MS_FAILURE;
1269   }
1270 
1271   return_value = msCopyLegend(&(dst->legend), &(src->legend),dst);
1272   if (return_value != MS_SUCCESS) {
1273     msSetError(MS_MEMERR, "Failed to copy legend.", "msCopyMap()");
1274     return MS_FAILURE;
1275   }
1276 
1277   return_value = msCopyQueryMap(&(dst->querymap), &(src->querymap));
1278   if (return_value != MS_SUCCESS) {
1279     msSetError(MS_MEMERR, "Failed to copy querymap.", "msCopyMap()");
1280     return MS_FAILURE;
1281   }
1282 
1283   return_value = msCopyWeb(&(dst->web), &(src->web), dst);
1284   if (return_value != MS_SUCCESS) {
1285     msSetError(MS_MEMERR, "Failed to copy web.", "msCopyMap()");
1286     return MS_FAILURE;
1287   }
1288 
1289   if( src->layerorder ) {
1290     for (i = 0; i < dst->numlayers; i++) {
1291         MS_COPYSTELEM(layerorder[i]);
1292     }
1293   }
1294   MS_COPYSTELEM(debug);
1295   MS_COPYSTRING(dst->datapattern, src->datapattern);
1296   MS_COPYSTRING(dst->templatepattern, src->templatepattern);
1297 
1298   if( msCopyHashTable( &(dst->configoptions), &(src->configoptions) ) != MS_SUCCESS )
1299     return MS_FAILURE;
1300 
1301   return MS_SUCCESS;
1302 }
1303 
msCopyRasterBuffer(rasterBufferObj * dst,const rasterBufferObj * src)1304 int msCopyRasterBuffer(rasterBufferObj *dst, const rasterBufferObj *src) {
1305   *dst = *src;
1306   if(src->type == MS_BUFFER_BYTE_RGBA) {
1307     dst->data.rgba = src->data.rgba;
1308     dst->data.rgba.pixels = msSmallMalloc(src->height * src->data.rgba.row_step);
1309     memcpy(dst->data.rgba.pixels, src->data.rgba.pixels, src->data.rgba.row_step*src->height);
1310     dst->data.rgba.r = dst->data.rgba.pixels + (src->data.rgba.r - src->data.rgba.pixels);
1311     dst->data.rgba.g = dst->data.rgba.pixels + (src->data.rgba.g - src->data.rgba.pixels);
1312     dst->data.rgba.b = dst->data.rgba.pixels + (src->data.rgba.b - src->data.rgba.pixels);
1313     if(src->data.rgba.a) {
1314       dst->data.rgba.a = dst->data.rgba.pixels + (src->data.rgba.a - src->data.rgba.pixels);
1315     } else {
1316       dst->data.rgba.a = NULL;
1317     }
1318   }
1319   return MS_SUCCESS;
1320 }
1321 
1322