PostGIS  3.0.0dev-r@@SVN_REVISION@@
lwutil.c
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * PostGIS - Spatial Types for PostgreSQL
4  * http://postgis.net
5  *
6  * PostGIS is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * PostGIS is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with PostGIS. If not, see <http://www.gnu.org/licenses/>.
18  *
19  **********************************************************************
20  *
21  * Copyright (C) 2004-2015 Sandro Santilli <strk@kbt.io>
22  * Copyright (C) 2006 Mark Leslie <mark.leslie@lisasoft.com>
23  * Copyright (C) 2008-2009 Mark Cave-Ayland <mark.cave-ayland@siriusit.co.uk>
24  * Copyright (C) 2009-2015 Paul Ramsey <pramsey@cleverelephant.ca>
25  * Copyright (C) 2010 Olivier Courtin <olivier.courtin@camptocamp.com>
26  *
27  **********************************************************************/
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <stdarg.h>
32 #include <string.h>
33 #include <ctype.h> /* for tolower */
34 
35 /* Global variables */
36 #include "../postgis_config.h"
37 #include "liblwgeom_internal.h"
38 #include "lwgeom_log.h"
39 
40 /* Default allocators */
41 static void * default_allocator(size_t size);
42 static void default_freeor(void *mem);
43 static void * default_reallocator(void *mem, size_t size);
47 
48 /* Default reporters */
49 static void default_noticereporter(const char *fmt, va_list ap);
50 static void default_errorreporter(const char *fmt, va_list ap);
53 
54 /* Default logger */
55 static void default_debuglogger(int level, const char *fmt, va_list ap);
57 
58 #define LW_MSG_MAXLEN 256
59 
60 static char *lwgeomTypeName[] =
61 {
62  "Unknown",
63  "Point",
64  "LineString",
65  "Polygon",
66  "MultiPoint",
67  "MultiLineString",
68  "MultiPolygon",
69  "GeometryCollection",
70  "CircularString",
71  "CompoundCurve",
72  "CurvePolygon",
73  "MultiCurve",
74  "MultiSurface",
75  "PolyhedralSurface",
76  "Triangle",
77  "Tin"
78 };
79 
80 /*
81  * Default allocators
82  *
83  * We include some default allocators that use malloc/free/realloc
84  * along with stdout/stderr since this is the most common use case
85  *
86  */
87 
88 static void *
89 default_allocator(size_t size)
90 {
91  void *mem = malloc(size);
92  return mem;
93 }
94 
95 static void
96 default_freeor(void *mem)
97 {
98  free(mem);
99 }
100 
101 static void *
102 default_reallocator(void *mem, size_t size)
103 {
104  void *ret = realloc(mem, size);
105  return ret;
106 }
107 
108 /*
109  * Default lwnotice/lwerror handlers
110  *
111  * Since variadic functions cannot pass their parameters directly, we need
112  * wrappers for these functions to convert the arguments into a va_list
113  * structure.
114  */
115 
116 static void
117 default_noticereporter(const char *fmt, va_list ap)
118 {
119  char msg[LW_MSG_MAXLEN+1];
120  vsnprintf (msg, LW_MSG_MAXLEN, fmt, ap);
121  msg[LW_MSG_MAXLEN]='\0';
122  fprintf(stderr, "%s\n", msg);
123 }
124 
125 static void
126 default_debuglogger(int level, const char *fmt, va_list ap)
127 {
128  char msg[LW_MSG_MAXLEN+1];
129  if ( POSTGIS_DEBUG_LEVEL >= level )
130  {
131  /* Space pad the debug output */
132  int i;
133  for ( i = 0; i < level; i++ )
134  msg[i] = ' ';
135  vsnprintf(msg+i, LW_MSG_MAXLEN-i, fmt, ap);
136  msg[LW_MSG_MAXLEN]='\0';
137  fprintf(stderr, "%s\n", msg);
138  }
139 }
140 
141 static void
142 default_errorreporter(const char *fmt, va_list ap)
143 {
144  char msg[LW_MSG_MAXLEN+1];
145  vsnprintf (msg, LW_MSG_MAXLEN, fmt, ap);
146  msg[LW_MSG_MAXLEN]='\0';
147  fprintf(stderr, "%s\n", msg);
148  exit(1);
149 }
150 
157 void
159  lwfreeor freeor, lwreporter errorreporter,
160  lwreporter noticereporter) {
161 
162  if ( allocator ) lwalloc_var = allocator;
163  if ( reallocator ) lwrealloc_var = reallocator;
164  if ( freeor ) lwfree_var = freeor;
165 
166  if ( errorreporter ) lwerror_var = errorreporter;
167  if ( noticereporter ) lwnotice_var = noticereporter;
168 }
169 
170 void
172 
173  if ( debuglogger ) lwdebug_var = debuglogger;
174 }
175 
176 void
177 lwnotice(const char *fmt, ...)
178 {
179  va_list ap;
180 
181  va_start(ap, fmt);
182 
183  /* Call the supplied function */
184  (*lwnotice_var)(fmt, ap);
185 
186  va_end(ap);
187 }
188 
189 void
190 lwerror(const char *fmt, ...)
191 {
192  va_list ap;
193 
194  va_start(ap, fmt);
195 
196  /* Call the supplied function */
197  (*lwerror_var)(fmt, ap);
198 
199  va_end(ap);
200 }
201 
202 void
203 lwdebug(int level, const char *fmt, ...)
204 {
205  va_list ap;
206 
207  va_start(ap, fmt);
208 
209  /* Call the supplied function */
210  (*lwdebug_var)(level, fmt, ap);
211 
212  va_end(ap);
213 }
214 
215 const char*
217 {
218  if ( type > 15 )
219  {
220  /* assert(0); */
221  return "Invalid type";
222  }
223  return lwgeomTypeName[(int ) type];
224 }
225 
226 void *
227 lwalloc(size_t size)
228 {
229  void *mem = lwalloc_var(size);
230  LWDEBUGF(5, "lwalloc: %d@%p", size, mem);
231  return mem;
232 }
233 
234 void *
235 lwrealloc(void *mem, size_t size)
236 {
237  LWDEBUGF(5, "lwrealloc: %d@%p", size, mem);
238  return lwrealloc_var(mem, size);
239 }
240 
241 void
242 lwfree(void *mem)
243 {
244  lwfree_var(mem);
245 }
246 
247 /*
248  * Returns a new string which contains a maximum of maxlength characters starting
249  * from startpos and finishing at endpos (0-based indexing). If the string is
250  * truncated then the first or last characters are replaced by "..." as
251  * appropriate.
252  *
253  * The caller should specify start or end truncation by setting the truncdirection
254  * parameter as follows:
255  * 0 - start truncation (i.e. characters are removed from the beginning)
256  * 1 - end truncation (i.e. characters are removed from the end)
257  */
258 
259 char *lwmessage_truncate(char *str, int startpos, int endpos, int maxlength, int truncdirection)
260 {
261  char *output;
262  char *outstart;
263 
264  /* Allocate space for new string */
265  output = lwalloc(maxlength + 4);
266  output[0] = '\0';
267 
268  /* Start truncation */
269  if (truncdirection == 0)
270  {
271  /* Calculate the start position */
272  if (endpos - startpos < maxlength)
273  {
274  outstart = str + startpos;
275  strncat(output, outstart, endpos - startpos + 1);
276  }
277  else
278  {
279  if (maxlength >= 3)
280  {
281  /* Add "..." prefix */
282  outstart = str + endpos + 1 - maxlength + 3;
283  strncat(output, "...", 3);
284  strncat(output, outstart, maxlength - 3);
285  }
286  else
287  {
288  /* maxlength is too small; just output "..." */
289  strncat(output, "...", 3);
290  }
291  }
292  }
293 
294  /* End truncation */
295  if (truncdirection == 1)
296  {
297  /* Calculate the end position */
298  if (endpos - startpos < maxlength)
299  {
300  outstart = str + startpos;
301  strncat(output, outstart, endpos - startpos + 1);
302  }
303  else
304  {
305  if (maxlength >= 3)
306  {
307  /* Add "..." suffix */
308  outstart = str + startpos;
309  strncat(output, outstart, maxlength - 3);
310  strncat(output, "...", 3);
311  }
312  else
313  {
314  /* maxlength is too small; just output "..." */
315  strncat(output, "...", 3);
316  }
317  }
318  }
319 
320  return output;
321 }
322 
323 
324 char
326 {
327  static int endian_check_int = 1; /* don't modify this!!! */
328 
329  return *((char *) &endian_check_int); /* 0 = big endian | xdr,
330  * 1 = little endian | ndr
331  */
332 }
333 
334 
335 void
336 error_if_srid_mismatch(int srid1, int srid2)
337 {
338  if ( srid1 != srid2 )
339  {
340  lwerror("Operation on mixed SRID geometries");
341  }
342 }
343 
344 int
345 clamp_srid(int srid)
346 {
347  int newsrid = srid;
348 
349  if ( newsrid <= 0 ) {
350  if ( newsrid != SRID_UNKNOWN ) {
351  newsrid = SRID_UNKNOWN;
352  lwnotice("SRID value %d converted to the officially unknown SRID value %d", srid, newsrid);
353  }
354  } else if ( srid > SRID_MAXIMUM ) {
355  newsrid = SRID_USER_MAXIMUM + 1 +
356  /* -1 is to reduce likelyhood of clashes */
357  /* NOTE: must match implementation in postgis_restore.pl */
358  ( srid % ( SRID_MAXIMUM - SRID_USER_MAXIMUM - 1 ) );
359  lwnotice("SRID value %d > SRID_MAXIMUM converted to %d", srid, newsrid);
360  }
361 
362  return newsrid;
363 }
364 
void lwdebug(int level, const char *fmt,...)
Write a debug message out.
Definition: lwutil.c:203
static void * default_allocator(size_t size)
Definition: lwutil.c:89
char getMachineEndian(void)
Definition: lwutil.c:325
static void default_debuglogger(int level, const char *fmt, va_list ap)
Definition: lwutil.c:126
def fmt
Definition: pixval.py:92
static void default_freeor(void *mem)
Definition: lwutil.c:96
void lwgeom_set_debuglogger(lwdebuglogger debuglogger)
Definition: lwutil.c:171
void lwfree(void *mem)
Definition: lwutil.c:242
int clamp_srid(int srid)
Return a valid SRID from an arbitrary integer Raises a notice if what comes out is different from wha...
Definition: lwutil.c:345
lwallocator lwalloc_var
Definition: lwutil.c:44
void(* lwfreeor)(void *mem)
Definition: liblwgeom.h:219
static char * lwgeomTypeName[]
Definition: lwutil.c:60
#define SRID_USER_MAXIMUM
Maximum valid SRID value for the user We reserve 1000 values for internal use.
Definition: liblwgeom.h:184
void * lwrealloc(void *mem, size_t size)
Definition: lwutil.c:235
void *(* lwallocator)(size_t size)
Global functions for memory/logging handlers.
Definition: liblwgeom.h:217
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:187
void lwnotice(const char *fmt,...)
Write a notice out to the notice handler.
Definition: lwutil.c:177
lwreporter lwerror_var
Definition: lwutil.c:52
void(* lwreporter)(const char *fmt, va_list ap) __attribute__((format(printf
Definition: liblwgeom.h:220
void *(* lwreallocator)(void *mem, size_t size)
Definition: liblwgeom.h:218
lwreporter lwnotice_var
Definition: lwutil.c:51
static void default_errorreporter(const char *fmt, va_list ap)
Definition: lwutil.c:142
static void default_noticereporter(const char *fmt, va_list ap)
Definition: lwutil.c:117
void(*) typedef void(* lwdebuglogger)(int level, const char *fmt, va_list ap) __attribute__((format(printf
Definition: liblwgeom.h:222
static void * default_reallocator(void *mem, size_t size)
Definition: lwutil.c:102
type
Definition: ovdump.py:41
lwreallocator lwrealloc_var
Definition: lwutil.c:45
void free(void *)
void * malloc(YYSIZE_T)
#define SRID_MAXIMUM
Maximum allowed SRID value in serialized geometry.
Definition: liblwgeom.h:178
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
unsigned char uint8_t
Definition: uthash.h:79
void lwgeom_set_handlers(lwallocator allocator, lwreallocator reallocator, lwfreeor freeor, lwreporter errorreporter, lwreporter noticereporter)
This function is called by programs which want to set up custom handling for memory management and er...
Definition: lwutil.c:158
lwdebuglogger lwdebug_var
Definition: lwutil.c:56
char * lwmessage_truncate(char *str, int startpos, int endpos, int maxlength, int truncdirection)
Definition: lwutil.c:259
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:216
void * lwalloc(size_t size)
Definition: lwutil.c:227
void error_if_srid_mismatch(int srid1, int srid2)
Definition: lwutil.c:336
#define LW_MSG_MAXLEN
Definition: lwutil.c:58
lwfreeor lwfree_var
Definition: lwutil.c:46