librtree 0.9.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +72 -0
  3. data/COPYING +21 -0
  4. data/README.md +86 -0
  5. data/ext/rtree/extconf.rb +37 -19
  6. data/ext/rtree/lib/bindex.c +157 -0
  7. data/ext/rtree/lib/bindex.h +31 -0
  8. data/ext/rtree/lib/bounds.h +21 -0
  9. data/ext/rtree/lib/branch.c +51 -0
  10. data/ext/rtree/lib/branches.c +17 -0
  11. data/ext/rtree/lib/bsrt.c +704 -0
  12. data/ext/rtree/lib/bsrt.h +16 -0
  13. data/ext/rtree/lib/constants.h +19 -0
  14. data/ext/rtree/lib/csv.c +81 -0
  15. data/ext/rtree/lib/csv.h +16 -0
  16. data/ext/rtree/lib/endianness.h +83 -0
  17. data/ext/rtree/lib/error.c +47 -0
  18. data/ext/rtree/lib/json.c +491 -0
  19. data/ext/rtree/lib/json.h +16 -0
  20. data/ext/rtree/lib/mk/Hdr.mk +3 -0
  21. data/ext/rtree/lib/mk/MakeDepend +25 -0
  22. data/ext/rtree/lib/mk/Obj.mk +3 -0
  23. data/ext/rtree/lib/node.c +708 -0
  24. data/ext/rtree/lib/package.c +11 -0
  25. data/ext/rtree/lib/page.c +47 -0
  26. data/ext/rtree/lib/page.h +13 -0
  27. data/ext/rtree/lib/postscript.c +543 -0
  28. data/ext/rtree/lib/rect.c +139 -0
  29. data/ext/rtree/lib/rectf.c +219 -0
  30. data/ext/rtree/lib/rtree/branch.h +105 -0
  31. data/ext/rtree/lib/rtree/branches.h +38 -0
  32. data/ext/rtree/lib/rtree/error.h +42 -0
  33. data/ext/rtree/lib/rtree/extent.h +20 -0
  34. data/ext/rtree/lib/rtree/node.h +92 -0
  35. data/ext/rtree/lib/rtree/package.h +14 -0
  36. data/ext/rtree/lib/rtree/postscript.h +66 -0
  37. data/ext/rtree/lib/rtree/rect.h +38 -0
  38. data/ext/rtree/lib/rtree/rectf.h +34 -0
  39. data/ext/rtree/lib/rtree/search.h +27 -0
  40. data/ext/rtree/lib/rtree/state.h +113 -0
  41. data/ext/rtree/lib/rtree/types.h +14 -0
  42. data/ext/rtree/lib/rtree-base.c +190 -0
  43. data/ext/rtree/lib/rtree.h +61 -0
  44. data/ext/rtree/lib/search.c +54 -0
  45. data/ext/rtree/lib/split.c +710 -0
  46. data/ext/rtree/lib/split.h +15 -0
  47. data/ext/rtree/lib/spvol.c +48 -0
  48. data/ext/rtree/lib/spvol.h +13 -0
  49. data/ext/rtree/lib/state.c +169 -0
  50. metadata +50 -3
@@ -0,0 +1,704 @@
1
+ #ifdef HAVE_CONFIG_H
2
+ #include "config.h"
3
+ #endif
4
+
5
+ #include "bsrt.h"
6
+
7
+ #include "rtree/error.h"
8
+ #include "rtree/branches.h"
9
+
10
+ #include <errno.h>
11
+ #include <string.h>
12
+
13
+ #ifdef WITH_BSRT
14
+
15
+ #include "endianness.h"
16
+ #include "bounds.h"
17
+
18
+ #define BSRT_MAGIC "BSRt"
19
+ #define BSRT_FOOTER "fin"
20
+ #define BSRT_VERSION 2
21
+
22
+ /* magic number, 4 bytes */
23
+
24
+ static int write_magic(FILE *stream)
25
+ {
26
+ if (fwrite(BSRT_MAGIC, 1, 4, stream) != 4)
27
+ return RTREE_ERR_FWRITE;
28
+
29
+ return RTREE_OK;
30
+ }
31
+
32
+ /* version, 2 bytes */
33
+
34
+ static int write_version(FILE *stream)
35
+ {
36
+ uint16_t v = htole16(BSRT_VERSION);
37
+
38
+ if (fwrite(&v, 2, 1, stream) != 1)
39
+ return RTREE_ERR_FWRITE;
40
+
41
+ return RTREE_OK;
42
+ }
43
+
44
+ /* state, 12 bytes */
45
+
46
+ static int write_state(state_t *state, FILE *stream)
47
+ {
48
+ uint16_t v[6] =
49
+ {
50
+ htole16(state_dims(state)),
51
+ htole16(state_page_size(state)),
52
+ htole16(SIZEOF_RTREE_COORD_T),
53
+ htole16(state_rect_size(state)),
54
+ htole16(state_branch_size(state)),
55
+ htole16(state_node_size(state))
56
+ };
57
+
58
+ if (fwrite(&v, 2, 6, stream) != 6)
59
+ return RTREE_ERR_FWRITE;
60
+
61
+ return RTREE_OK;
62
+ }
63
+
64
+ /*
65
+ each node has a 4-byte header, the level (positive for an internal
66
+ node, zero for a leaf node) and the count of branches.
67
+ */
68
+
69
+ static int write_header(uint16_t level, uint16_t count, FILE *stream)
70
+ {
71
+ uint16_t v;
72
+
73
+ v = htole16(level);
74
+
75
+ if (fwrite(&v, 2, 1, stream) != 1)
76
+ return RTREE_ERR_FWRITE;
77
+
78
+ v = htole16(count);
79
+
80
+ if (fwrite(&v, 2, 1, stream) != 1)
81
+ return RTREE_ERR_FWRITE;
82
+
83
+ return RTREE_OK;
84
+ }
85
+
86
+ static int write_id(rtree_id_t id, FILE *stream)
87
+ {
88
+ #if SIZEOF_RTREE_ID_T == 2
89
+ uint16_t v = htole16(id);
90
+ #elif SIZEOF_RTREE_ID_T == 4
91
+ uint32_t v = htole32(id);
92
+ #elif SIZEOF_RTREE_ID_T == 8
93
+ uint64_t v = htole64(id);
94
+ #else
95
+ #error rtree_id_t size not handled
96
+ #endif
97
+
98
+ if (fwrite(&v, SIZEOF_RTREE_ID_T, 1, stream) != 1)
99
+ return RTREE_ERR_FWRITE;
100
+
101
+ return RTREE_OK;
102
+ }
103
+
104
+ /*
105
+ Here we only byte-swap if we establish that the host float
106
+ byte-order is big-endian, this saves time on little-endian
107
+ hardware. Note that in the big-endian case, we call htole32()
108
+ which converts from the host integer byte-order to little-endian,
109
+ this will only be correct if integer and float endianess are
110
+ the same, this is not true in general (!), there exists real
111
+ hardware with big-endian floats and little-endian integers.
112
+ So it would be better to use be32tole32() here, but that does
113
+ not exist (one could make it with htole32(be32toh()), but
114
+ these are macros not functions, one would need to test this on
115
+ real hardware first).
116
+ */
117
+
118
+ static int write_rect(const state_t *state,
119
+ const rtree_coord_t *rect,
120
+ FILE *stream)
121
+ {
122
+ size_t
123
+ n = 2 * state_dims(state),
124
+ k = SIZEOF_RTREE_COORD_T;
125
+
126
+ #ifdef FLOAT_WORDS_BIGENDIAN
127
+
128
+ rtree_coord_t buffer[n];
129
+
130
+ for (size_t i = 0 ; i < n ; i++)
131
+ {
132
+ /*
133
+ The type-punning to/from char* here is legal (the standard
134
+ makes an explicit exception), but cppcheck warns anyway, so
135
+ we suppress those warnings
136
+ */
137
+
138
+ char p[k];
139
+
140
+ /* cppcheck-suppress invalidPointerCast */
141
+ *(rtree_coord_t*)p = rect[i];
142
+
143
+ #if SIZEOF_RTREE_COORD_T == 4
144
+ /* cppcheck-suppress invalidPointerCast */
145
+ *(uint32_t*)p = htole32(*(uint32_t*)p);
146
+ #elif SIZEOF_RTREE_COORD_T == 8
147
+ /* cppcheck-suppress invalidPointerCast */
148
+ *(uint64_t*)p = htole64(*(uint64_t*)p);
149
+ #else
150
+ #error rtree_coord_t size not handled
151
+ #endif
152
+
153
+ /* cppcheck-suppress invalidPointerCast */
154
+ buffer[i] = *(rtree_coord_t*)p;
155
+ }
156
+
157
+ if (fwrite(buffer, k, n, stream) != n)
158
+ return RTREE_ERR_FWRITE;
159
+ return RTREE_OK;
160
+
161
+ #else
162
+
163
+ if (fwrite(rect, k, n, stream) != n)
164
+ return RTREE_ERR_FWRITE;
165
+ return RTREE_OK;
166
+
167
+ #endif
168
+ }
169
+
170
+ static int write_node(const state_t*, const node_t*, FILE*);
171
+
172
+ /* callbacks passed to node_branch_each() */
173
+
174
+ static int write_internal_branch(const state_t *state,
175
+ const branch_t *branch,
176
+ void *arg)
177
+ {
178
+ FILE *stream = arg;
179
+ int err;
180
+
181
+ if ((err = write_rect(state, branch->rect, stream)) != 0)
182
+ return err;
183
+
184
+ const node_t *child = branch_get_child(branch);
185
+
186
+ if ((err = write_node(state, child, stream)) != 0)
187
+ return err;
188
+
189
+ return 0;
190
+ }
191
+
192
+ static int write_leaf_branch(const state_t *state,
193
+ const branch_t *branch,
194
+ void *arg)
195
+ {
196
+ FILE *stream = arg;
197
+ int err;
198
+
199
+ if ((err = write_rect(state, branch->rect, stream)) != 0)
200
+ return err;
201
+
202
+ rtree_id_t id = branch_get_id(branch);
203
+
204
+ if ((err = write_id(id, stream)) != 0)
205
+ return err;
206
+
207
+ return 0;
208
+ }
209
+
210
+ /* write internal/leaf nodes */
211
+
212
+ static int write_internal_node(const state_t *state,
213
+ const node_t *node,
214
+ FILE *stream)
215
+ {
216
+ int err;
217
+
218
+ if ((err = write_header(node_level(node), node_count(node), stream)) != 0)
219
+ return err;
220
+
221
+ return node_branch_each(state, node, write_internal_branch, stream);
222
+ }
223
+
224
+ static int write_leaf_node(const state_t *state,
225
+ const node_t *node,
226
+ FILE *stream)
227
+ {
228
+ int err;
229
+
230
+ if ((err = write_header(node_level(node), node_count(node), stream)) != 0)
231
+ return err;
232
+
233
+ return node_branch_each(state, node, write_leaf_branch, stream);
234
+ }
235
+
236
+ static int write_node(const state_t *state,
237
+ const node_t *node,
238
+ FILE *stream)
239
+ {
240
+ int err;
241
+
242
+ if (node_level(node) > 0)
243
+ err = write_internal_node(state, node, stream);
244
+ else
245
+ err = write_leaf_node(state, node, stream);
246
+
247
+ return err;
248
+ }
249
+
250
+ static int write_footer(FILE *stream)
251
+ {
252
+ size_t n = strlen(BSRT_FOOTER);
253
+ if (fwrite(BSRT_FOOTER, 1, n, stream) != n)
254
+ return RTREE_ERR_FWRITE;
255
+ return RTREE_OK;
256
+ }
257
+
258
+ int bsrt_rtree_write(const rtree_t *rtree, FILE *stream)
259
+ {
260
+ int err;
261
+
262
+ if ((err = write_magic(stream)) != 0)
263
+ return err;
264
+
265
+ if ((err = write_version(stream)) != 0)
266
+ return err;
267
+
268
+ if ((err = write_state(rtree->state, stream)) != 0)
269
+ return err;
270
+
271
+ if ((err = write_node(rtree->state, rtree->root, stream)) != 0)
272
+ return err;
273
+
274
+ if ((err = write_footer(stream)) != 0)
275
+ return err;
276
+
277
+ return RTREE_OK;
278
+ }
279
+
280
+ /*
281
+ reader functions, unlike the writer, all functions acting on
282
+ file content after the version are version qualified, the idea
283
+ being that later versions of the library should be able to
284
+ read all previous versions of the format.
285
+ */
286
+
287
+ static int read_magic(FILE *stream)
288
+ {
289
+ char buffer[4];
290
+
291
+ if (fread(buffer, 1, 4, stream) != 4)
292
+ return 1;
293
+
294
+ if (memcmp(buffer, BSRT_MAGIC, 4) == 0)
295
+ return 0;
296
+
297
+ errno = EINVAL;
298
+ return 1;
299
+ }
300
+
301
+ static int read_version(FILE *stream, uint16_t *v)
302
+ {
303
+ if (fread(v, 2, 1, stream) != 1)
304
+ return 1;
305
+
306
+ *v = le16toh(*v);
307
+
308
+ return 0;
309
+ }
310
+
311
+ /* read v1 */
312
+
313
+ static int read_v1_header(FILE *stream, uint16_t v[5])
314
+ {
315
+ if (fread(v, 2, 5, stream) != 5)
316
+ return 1;
317
+
318
+ for (size_t i = 0 ; i < 5 ; i++)
319
+ v[i] = le16toh(v[i]);
320
+
321
+ return 0;
322
+ }
323
+
324
+ static bool read_v1_state_consistent(uint16_t v[5], const state_t *state)
325
+ {
326
+ return
327
+ (v[0] == state_dims(state)) &&
328
+ (v[1] == state_page_size(state)) &&
329
+ (v[2] == SIZEOF_RTREE_COORD_T) &&
330
+ (v[3] == state_rect_size(state)) &&
331
+ (v[4] == state_branch_size(state));
332
+ }
333
+
334
+ /* see note above on float/double endianness */
335
+
336
+ static int read_v1_rect(FILE *stream,
337
+ const state_t *state,
338
+ rtree_coord_t *rect)
339
+ {
340
+ size_t
341
+ n = 2 * state_dims(state),
342
+ k = SIZEOF_RTREE_COORD_T;
343
+
344
+ #ifdef FLOAT_WORDS_BIGENDIAN
345
+
346
+ char buffer[n * k];
347
+
348
+ if (fread(buffer, k, n, stream) != n)
349
+ return 1;
350
+
351
+ for (size_t i = 0 ; i < n ; i++)
352
+ {
353
+ char *p = buffer + i * k;
354
+
355
+ #if SIZEOF_RTREE_COORD_T == 4
356
+ *(uint32_t*)p = le32toh(*(uint32_t*)p);
357
+ #elif SIZEOF_RTREE_COORD_T == 8
358
+ *(uint64_t*)p = le64toh(*(uint64_t*)p);
359
+ #else
360
+ #error rtree_coord_t size not handled
361
+ #endif
362
+
363
+ /* cppcheck-suppress invalidPointerCast */
364
+
365
+ rect[i] = *(rtree_coord_t*)p;
366
+ }
367
+
368
+ #else
369
+
370
+ if (fread(rect, k, n, stream) != n)
371
+ return 1;
372
+
373
+ #endif
374
+
375
+ return 0;
376
+ }
377
+
378
+ static int read_v1_id(FILE *stream, rtree_id_t *id)
379
+ {
380
+ if (fread(id, SIZEOF_RTREE_ID_T, 1, stream) != 1)
381
+ return 1;
382
+
383
+ #if SIZEOF_RTREE_ID_T == 8
384
+ *id = le64toh(*id);
385
+ #elif SIZEOF_RTREE_ID_T == 4
386
+ *id = le32toh(*id);
387
+ #elif SIZEOF_RTREE_ID_T == 2
388
+ *id = le16toh(*id);
389
+ #else
390
+ #error rtree_id_t size not handled
391
+ #endif
392
+
393
+ return 0;
394
+ }
395
+
396
+ static node_t* read_v1_node(FILE*, const state_t*);
397
+
398
+ static int read_v1_branch_internal(FILE *stream,
399
+ const state_t *state,
400
+ branch_t *branch)
401
+ {
402
+ if (branch_init(state, branch) != 0)
403
+ return 1;
404
+
405
+ if (read_v1_rect(stream, state, branch_get_rect_mutable(branch)) != 0)
406
+ return 1;
407
+
408
+ node_t *child;
409
+
410
+ if ((child = read_v1_node(stream, state)) == NULL)
411
+ return 1;
412
+
413
+ branch_set_child(branch, child);
414
+
415
+ return 0;
416
+ }
417
+
418
+ static int read_v1_branch_leaf(FILE *stream,
419
+ const state_t *state,
420
+ branch_t *branch)
421
+ {
422
+ if (branch_init(state, branch) != 0)
423
+ return 1;
424
+
425
+ if (read_v1_rect(stream, state, branch_get_rect_mutable(branch)) != 0)
426
+ return 1;
427
+
428
+ rtree_id_t id;
429
+
430
+ if (read_v1_id(stream, &id) != 0)
431
+ return 1;
432
+
433
+ branch_set_id(branch, id);
434
+
435
+ return 0;
436
+ }
437
+
438
+ typedef int (branch_read_t)(FILE*, const state_t*, branch_t*);
439
+
440
+ static node_t* read_v1_node_generic(FILE *stream,
441
+ branch_read_t *f,
442
+ const state_t *state,
443
+ uint16_t n)
444
+ {
445
+ if (n > state_branching_factor(state))
446
+ {
447
+ errno = EINVAL;
448
+ return NULL;
449
+ }
450
+
451
+ node_t *node;
452
+
453
+ if ((node = node_new(state)) != NULL)
454
+ {
455
+ void *branches = node_get_branches(node);
456
+
457
+ for (size_t i = 0 ; i < n ; i++)
458
+ {
459
+ branch_t *branch = branches_get(state, branches, i);
460
+ if (f(stream, state, branch) != 0)
461
+ break;
462
+ node_count_increment(node);
463
+ }
464
+
465
+ if (node_count(node) == n)
466
+ return node;
467
+
468
+ errno = EINVAL;
469
+ node_destroy(state, node);
470
+ }
471
+
472
+ return NULL;
473
+ }
474
+
475
+ static node_t* read_v1_node_internal(FILE *stream,
476
+ const state_t *state,
477
+ uint16_t n)
478
+ {
479
+ return read_v1_node_generic(stream, read_v1_branch_internal, state, n);
480
+ }
481
+
482
+ static node_t* read_v1_node_leaf(FILE *stream,
483
+ const state_t *state,
484
+ uint16_t n)
485
+ {
486
+ return read_v1_node_generic(stream, read_v1_branch_leaf, state, n);
487
+ }
488
+
489
+ static node_t* read_v1_node(FILE *stream, const state_t *state)
490
+ {
491
+ uint16_t level;
492
+
493
+ if (fread(&level, 2, 1, stream) != 1)
494
+ return NULL;
495
+ level = le16toh(level);
496
+ if (level > RTREE_LEVELS_MAX)
497
+ return NULL;
498
+
499
+ uint16_t count;
500
+
501
+ if (fread(&count, 2, 1, stream) != 1)
502
+ return NULL;
503
+ count = le16toh(count);
504
+ if (count > RTREE_BRANCHES_MAX)
505
+ return NULL;
506
+
507
+ node_t *node;
508
+
509
+ if (level > 0)
510
+ node = read_v1_node_internal(stream, state, count);
511
+ else
512
+ node = read_v1_node_leaf(stream, state, count);
513
+
514
+ if (node != NULL)
515
+ node_set_level(node, level);
516
+
517
+ return node;
518
+ }
519
+
520
+ static int read_v1_footer(FILE *stream)
521
+ {
522
+ size_t n = strlen(BSRT_FOOTER);
523
+ char buffer[n];
524
+
525
+ if (fread(buffer, 1, n, stream) != n)
526
+ return 1;
527
+
528
+ if (memcmp(buffer, BSRT_FOOTER, n) == 0)
529
+ return 0;
530
+ else
531
+ {
532
+ errno = EINVAL;
533
+ return 1;
534
+ }
535
+ }
536
+
537
+ static rtree_t* read_v1(FILE *stream)
538
+ {
539
+ uint16_t v[5];
540
+
541
+ if (read_v1_header(stream, v) != 0)
542
+ return NULL;
543
+
544
+ size_t dims = v[0];
545
+
546
+ if (dims > RTREE_DIMS_MAX)
547
+ return NULL;
548
+
549
+ state_t *state;
550
+
551
+ if ((state = state_new(dims, RTREE_NODE_PAGE(1))) != NULL)
552
+ {
553
+ if (read_v1_state_consistent(v, state))
554
+ {
555
+ node_t *root;
556
+
557
+ if ((root = read_v1_node(stream, state)) != NULL)
558
+ {
559
+ if (read_v1_footer(stream) == 0)
560
+ {
561
+ rtree_t *rtree;
562
+
563
+ if ((rtree = rtree_alloc()) != NULL)
564
+ {
565
+ rtree->state = state;
566
+ rtree->root = root;
567
+ return rtree;
568
+ }
569
+ }
570
+ node_destroy(state, root);
571
+ }
572
+ }
573
+ else
574
+ errno = EINVAL;
575
+
576
+ state_destroy(state);
577
+ }
578
+
579
+ return NULL;
580
+ }
581
+
582
+ /* read v2 */
583
+
584
+ static int read_v2_header(FILE *stream, uint16_t v[6])
585
+ {
586
+ if (fread(v, 2, 6, stream) != 6)
587
+ return 1;
588
+
589
+ for (size_t i = 0 ; i < 6 ; i++)
590
+ v[i] = le16toh(v[i]);
591
+
592
+ return 0;
593
+ }
594
+
595
+ static bool read_v2_state_consistent(uint16_t v[6], const state_t *state)
596
+ {
597
+ return
598
+ (v[0] == state_dims(state)) &&
599
+ (v[1] == state_page_size(state)) &&
600
+ (v[2] == SIZEOF_RTREE_COORD_T) &&
601
+ (v[3] == state_rect_size(state)) &&
602
+ (v[4] == state_branch_size(state)) &&
603
+ (v[5] == state_node_size(state));
604
+ }
605
+
606
+ static node_t* read_v2_node(FILE *stream, const state_t *state)
607
+ {
608
+ return read_v1_node(stream, state);
609
+ }
610
+
611
+ static int read_v2_footer(FILE *stream)
612
+ {
613
+ return read_v1_footer(stream);
614
+ }
615
+
616
+ static rtree_t* read_v2(FILE *stream)
617
+ {
618
+ uint16_t v[6];
619
+
620
+ if (read_v2_header(stream, v) != 0)
621
+ return NULL;
622
+
623
+ if ((v[5] == 0) || (v[1] < v[5]))
624
+ return NULL;
625
+
626
+ size_t
627
+ dims = v[0],
628
+ node_page = v[1] / v[5];
629
+ state_t *state;
630
+
631
+ if ((state = state_new(dims, RTREE_NODE_PAGE(node_page))) != NULL)
632
+ {
633
+ if (read_v2_state_consistent(v, state))
634
+ {
635
+ node_t *root;
636
+
637
+ if ((root = read_v2_node(stream, state)) != NULL)
638
+ {
639
+ if (read_v2_footer(stream) == 0)
640
+ {
641
+ rtree_t *rtree;
642
+
643
+ if ((rtree = rtree_alloc()) != NULL)
644
+ {
645
+ rtree->state = state;
646
+ rtree->root = root;
647
+ return rtree;
648
+ }
649
+ }
650
+ node_destroy(state, root);
651
+ }
652
+ }
653
+ else
654
+ errno = EINVAL;
655
+
656
+ state_destroy(state);
657
+ }
658
+
659
+ return NULL;
660
+ }
661
+
662
+ rtree_t* bsrt_rtree_read(FILE *stream)
663
+ {
664
+ if (read_magic(stream) != 0)
665
+ return NULL;
666
+
667
+ uint16_t version;
668
+
669
+ if (read_version(stream, &version) != 0)
670
+ return NULL;
671
+
672
+ switch (version)
673
+ {
674
+ case 1:
675
+ return read_v1(stream);
676
+ case 2:
677
+ return read_v2(stream);
678
+ default:
679
+ errno = EINVAL;
680
+ return NULL;
681
+ }
682
+ }
683
+
684
+ #else
685
+
686
+ #pragma GCC diagnostic push
687
+ #pragma GCC diagnostic ignored "-Wunused-parameter"
688
+ int bsrt_rtree_write(const rtree_t *rtree, FILE *stream)
689
+ {
690
+ errno = ENOSYS;
691
+ return RTREE_ERR_NOBSRT;
692
+ }
693
+ #pragma GCC diagnostic pop
694
+
695
+ #pragma GCC diagnostic push
696
+ #pragma GCC diagnostic ignored "-Wunused-parameter"
697
+ rtree_t* bsrt_rtree_read(FILE *stream)
698
+ {
699
+ errno = ENOSYS;
700
+ return NULL;
701
+ }
702
+ #pragma GCC diagnostic pop
703
+
704
+ #endif
@@ -0,0 +1,16 @@
1
+ /*
2
+ bsrt.h
3
+ Copyright (c) J.J. Green 2019
4
+ */
5
+
6
+ #ifndef BSRT_H
7
+ #define BSRT_H
8
+
9
+ #include <stdio.h>
10
+
11
+ #include <rtree.h>
12
+
13
+ int bsrt_rtree_write(const rtree_t*, FILE*);
14
+ rtree_t* bsrt_rtree_read(FILE*);
15
+
16
+ #endif
@@ -0,0 +1,19 @@
1
+ /*
2
+ constants.h
3
+ Copyright (c) J.J. Green 2019
4
+ */
5
+
6
+ #ifndef CONSTANTS_H
7
+ #define CONSTANTS_H
8
+
9
+ #include <math.h>
10
+
11
+ #ifndef M_PI
12
+ #define M_PI 3.14159265358979323846
13
+ #endif
14
+
15
+ #ifndef M_LOG_PI
16
+ #define M_LOG_PI 1.1447298858494002
17
+ #endif
18
+
19
+ #endif