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