1 /*
2  *
3  * WKTRaster - Raster Types for PostGIS
4  * http://trac.osgeo.org/postgis/wiki/WKTRaster
5  *
6  * Copyright (C) 2011-2013 Regents of the University of California
7  *   <bkpark@ucdavis.edu>
8  * Copyright (C) 2010-2011 Jorge Arevalo <jorge.arevalo@deimos-space.com>
9  * Copyright (C) 2010-2011 David Zwarg <dzwarg@azavea.com>
10  * Copyright (C) 2009-2011 Pierre Racine <pierre.racine@sbf.ulaval.ca>
11  * Copyright (C) 2009-2011 Mateusz Loskot <mateusz@loskot.net>
12  * Copyright (C) 2008-2009 Sandro Santilli <strk@kbt.io>
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software Foundation,
26  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27  *
28  */
29 
30 #include <stdarg.h> /* for va_list, va_start etc */
31 
32 #include "librtcore.h"
33 #include "librtcore_internal.h"
34 
35 /******************************************************************************
36 * rt_context
37 ******************************************************************************/
38 
39 /*
40  * Default allocators
41  *
42  * We include some default allocators that use malloc/free/realloc
43  * along with stdout/stderr since this is the most common use case
44  *
45  */
46 void *
default_rt_allocator(size_t size)47 default_rt_allocator(size_t size)
48 {
49     void *mem = malloc(size);
50     return mem;
51 }
52 
53 void *
default_rt_reallocator(void * mem,size_t size)54 default_rt_reallocator(void *mem, size_t size)
55 {
56     void *ret = realloc(mem, size);
57     return ret;
58 }
59 
60 void
default_rt_deallocator(void * mem)61 default_rt_deallocator(void *mem)
62 {
63     free(mem);
64 }
65 
66 void
default_rt_error_handler(const char * fmt,va_list ap)67 default_rt_error_handler(const char *fmt, va_list ap) {
68 
69     static const char *label = "ERROR: ";
70     char newfmt[1024] = {0};
71     snprintf(newfmt, 1024, "%s%s\n", label, fmt);
72     newfmt[1023] = '\0';
73 
74     vprintf(newfmt, ap);
75 
76     va_end(ap);
77 }
78 
79 void
default_rt_warning_handler(const char * fmt,va_list ap)80 default_rt_warning_handler(const char *fmt, va_list ap) {
81 
82     static const char *label = "WARNING: ";
83     char newfmt[1024] = {0};
84     snprintf(newfmt, 1024, "%s%s\n", label, fmt);
85     newfmt[1023] = '\0';
86 
87     vprintf(newfmt, ap);
88 
89     va_end(ap);
90 }
91 
92 void
default_rt_info_handler(const char * fmt,va_list ap)93 default_rt_info_handler(const char *fmt, va_list ap) {
94 
95     static const char *label = "INFO: ";
96     char newfmt[1024] = {0};
97     snprintf(newfmt, 1024, "%s%s\n", label, fmt);
98     newfmt[1023] = '\0';
99 
100     vprintf(newfmt, ap);
101 
102     va_end(ap);
103 }
104 
default_rt_options(const char * varname)105 char * default_rt_options(const char* varname) {
106 	return NULL;
107 }
108 
109 
110 /**
111  * Struct definition here
112  */
113 struct rt_context_t {
114     rt_allocator alloc;
115     rt_reallocator realloc;
116     rt_deallocator dealloc;
117     rt_message_handler err;
118     rt_message_handler warn;
119     rt_message_handler info;
120     rt_options options;
121 };
122 
123 /* Static variable, to be used for all rt_core functions */
124 static struct rt_context_t ctx_t = {
125     .alloc = default_rt_allocator,
126     .realloc = default_rt_reallocator,
127     .dealloc = default_rt_deallocator,
128     .err = default_rt_error_handler,
129     .warn = default_rt_warning_handler,
130     .info = default_rt_info_handler,
131     .options = default_rt_options
132 };
133 
134 
135 /**
136  * Useful in raster core testing and in the (future)
137  * loader, when we need to use raster core functions but we don't have
138  * PostgreSQL backend behind. We must take care of memory by ourselves in those
139  * situations
140  */
141 void
rt_install_default_allocators(void)142 rt_install_default_allocators(void)
143 {
144     ctx_t.alloc = default_rt_allocator;
145     ctx_t.realloc = default_rt_reallocator;
146     ctx_t.dealloc = default_rt_deallocator;
147     ctx_t.err = default_rt_error_handler;
148     ctx_t.info = default_rt_info_handler;
149     ctx_t.warn = default_rt_warning_handler;
150     ctx_t.options = default_rt_options;
151 }
152 
153 
154 /**
155  * This function is called when the PostgreSQL backend is
156  * taking care of the memory and we want to use palloc family
157  */
158 void
rt_set_handlers(rt_allocator allocator,rt_reallocator reallocator,rt_deallocator deallocator,rt_message_handler error_handler,rt_message_handler info_handler,rt_message_handler warning_handler)159 rt_set_handlers(rt_allocator allocator, rt_reallocator reallocator,
160     rt_deallocator deallocator, rt_message_handler error_handler,
161     rt_message_handler info_handler, rt_message_handler warning_handler)
162 {
163     rt_set_handlers_options(allocator, reallocator, deallocator,
164     	error_handler, info_handler, warning_handler,
165         default_rt_options);
166 }
167 
168 void
rt_set_handlers_options(rt_allocator allocator,rt_reallocator reallocator,rt_deallocator deallocator,rt_message_handler error_handler,rt_message_handler info_handler,rt_message_handler warning_handler,rt_options options_handler)169 rt_set_handlers_options(rt_allocator allocator, rt_reallocator reallocator,
170     rt_deallocator deallocator, rt_message_handler error_handler,
171     rt_message_handler info_handler, rt_message_handler warning_handler,
172     rt_options options_handler)
173 {
174     ctx_t.alloc   = allocator;
175     ctx_t.realloc = reallocator;
176     ctx_t.dealloc = deallocator;
177 
178     ctx_t.err  = error_handler;
179     ctx_t.info = info_handler;
180     ctx_t.warn = warning_handler;
181 
182     ctx_t.options = options_handler;
183 }
184 
185 /**
186  * Raster core memory management functions.
187  *
188  * They use the functions defined by the caller.
189  */
190 void *
rtalloc(size_t size)191 rtalloc(size_t size) {
192     void * mem = ctx_t.alloc(size);
193     RASTER_DEBUGF(5, "rtalloc called: %d@%p", size, mem);
194     return mem;
195 }
196 
197 
198 void *
rtrealloc(void * mem,size_t size)199 rtrealloc(void * mem, size_t size) {
200     void * result = ctx_t.realloc(mem, size);
201     RASTER_DEBUGF(5, "rtrealloc called: %d@%p", size, result);
202     return result;
203 }
204 
205 void
rtdealloc(void * mem)206 rtdealloc(void * mem) {
207     ctx_t.dealloc(mem);
208     RASTER_DEBUG(5, "rtdealloc called");
209 }
210 
211 /**
212  * Raster core error and info handlers
213  *
214  * Since variadic functions cannot pass their parameters directly, we need
215  * wrappers for these functions to convert the arguments into a va_list
216  * structure.
217  */
218 void
rterror(const char * fmt,...)219 rterror(const char *fmt, ...) {
220     va_list ap;
221 
222     va_start(ap, fmt);
223 
224     /* Call the supplied function */
225     (*ctx_t.err)(fmt, ap);
226 
227     va_end(ap);
228 }
229 
230 void
rtinfo(const char * fmt,...)231 rtinfo(const char *fmt, ...) {
232     va_list ap;
233 
234     va_start(ap, fmt);
235 
236     /* Call the supplied function */
237     (*ctx_t.info)(fmt, ap);
238 
239     va_end(ap);
240 }
241 
242 
243 void
rtwarn(const char * fmt,...)244 rtwarn(const char *fmt, ...) {
245     va_list ap;
246 
247     va_start(ap, fmt);
248 
249     /* Call the supplied function */
250     (*ctx_t.warn)(fmt, ap);
251 
252     va_end(ap);
253 }
254 
255 char *
rtoptions(const char * varname)256 rtoptions(const char *varname) {
257 	if (!ctx_t.options)
258 		return NULL;
259 	return ctx_t.options(varname);
260 }
261 
262 char *
rtstrdup(const char * str)263 rtstrdup(const char *str) {
264 	size_t sz;
265 	char* dup;
266 	if (!str) return NULL;
267 	sz = strlen(str) + 1;
268 	dup = rtalloc(sz);
269 	memcpy(dup, str, sz);
270 	return dup;
271 }
272