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