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