mirror of
https://github.com/owntracks/recorder.git
synced 2026-02-13 20:49:51 +00:00
31
LICENSE
31
LICENSE
@@ -251,3 +251,34 @@ OpenLDAP is a registered trademark of the OpenLDAP Foundation.
|
||||
Copyright 1999-2003 The OpenLDAP Foundation, Redwood City,
|
||||
California, USA. All Rights Reserved. Permission to copy and
|
||||
distribute verbatim copies of this document is granted.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
## listsort
|
||||
http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.c
|
||||
|
||||
/*
|
||||
* This file is copyright 2001 Simon Tatham.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
6
Makefile
6
Makefile
@@ -12,7 +12,8 @@ OTR_OBJS = json.o \
|
||||
base64.o \
|
||||
misc.o \
|
||||
util.o \
|
||||
storage.o
|
||||
storage.o \
|
||||
listsort.o
|
||||
|
||||
CFLAGS += -DGHASHPREC=$(GHASHPREC)
|
||||
|
||||
@@ -78,8 +79,9 @@ http.o: http.c mongoose.h util.h http.h storage.h
|
||||
util.o: util.c util.h
|
||||
mongoose.o: mongoose.c mongoose.h
|
||||
ocat.o: ocat.c storage.h util.h version.h
|
||||
storage.o: storage.c storage.h util.h gcache.h
|
||||
storage.o: storage.c storage.h util.h gcache.h listsort.h
|
||||
hooks.o: hooks.c udata.h hooks.h util.h version.h gcache.h
|
||||
listsort.o: listsort.c listsort.h
|
||||
|
||||
|
||||
clean:
|
||||
|
||||
226
listsort.c
Normal file
226
listsort.c
Normal file
@@ -0,0 +1,226 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "listsort.h"
|
||||
|
||||
/* from http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.c */
|
||||
|
||||
/*
|
||||
* This file is copyright 2001 Simon Tatham.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
static double cmp(JsonNode * a, JsonNode * b)
|
||||
{
|
||||
JsonNode *ta = json_find_member(a, "tst");
|
||||
JsonNode *tb = json_find_member(b, "tst");
|
||||
//printf("a=%lf, b=%lf\n", ta->number_, tb->number_);
|
||||
|
||||
return ta->number_ - tb->number_;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the actual sort function. Notice that it returns the new head of
|
||||
* the list. (It has to, because the head will not generally be the same
|
||||
* element after the sort.) So unlike sorting an array, where you can do
|
||||
*
|
||||
* sort(myarray);
|
||||
*
|
||||
* you now have to do
|
||||
*
|
||||
* list = listsort(mylist);
|
||||
*/
|
||||
JsonNode *listsort(JsonNode * list, int is_circular, int is_double)
|
||||
{
|
||||
JsonNode *p, *q, *e, *tail, *oldhead;
|
||||
int insize, nmerges, psize, qsize, i;
|
||||
|
||||
/*
|
||||
* Silly special case: if `list' was passed in as NULL, return NULL
|
||||
* immediately.
|
||||
*/
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
insize = 1;
|
||||
|
||||
while (1) {
|
||||
p = list;
|
||||
oldhead = list; /* only used for circular linkage */
|
||||
list = NULL;
|
||||
tail = NULL;
|
||||
|
||||
nmerges = 0; /* count number of merges we do in this pass */
|
||||
|
||||
while (p) {
|
||||
nmerges++; /* there exists a merge to be done */
|
||||
/* step `insize' places along from p */
|
||||
q = p;
|
||||
psize = 0;
|
||||
for (i = 0; i < insize; i++) {
|
||||
psize++;
|
||||
if (is_circular)
|
||||
q = (q->next == oldhead ? NULL : q->next);
|
||||
else
|
||||
q = q->next;
|
||||
if (!q)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* if q hasn't fallen off end, we have two lists to
|
||||
* merge
|
||||
*/
|
||||
qsize = insize;
|
||||
|
||||
/* now we have two lists; merge them */
|
||||
while (psize > 0 || (qsize > 0 && q)) {
|
||||
|
||||
/*
|
||||
* decide whether next element of merge comes
|
||||
* from p or q
|
||||
*/
|
||||
if (psize == 0) {
|
||||
/* p is empty; e must come from q. */
|
||||
e = q;
|
||||
q = q->next;
|
||||
qsize--;
|
||||
if (is_circular && q == oldhead)
|
||||
q = NULL;
|
||||
} else if (qsize == 0 || !q) {
|
||||
/* q is empty; e must come from p. */
|
||||
e = p;
|
||||
p = p->next;
|
||||
psize--;
|
||||
if (is_circular && p == oldhead)
|
||||
p = NULL;
|
||||
} else if (cmp(p, q) <= 0) {
|
||||
/*
|
||||
* First element of p is lower (or
|
||||
* same); e must come from p.
|
||||
*/
|
||||
e = p;
|
||||
p = p->next;
|
||||
psize--;
|
||||
if (is_circular && p == oldhead)
|
||||
p = NULL;
|
||||
} else {
|
||||
/*
|
||||
* First element of q is lower; e
|
||||
* must come from q.
|
||||
*/
|
||||
e = q;
|
||||
q = q->next;
|
||||
qsize--;
|
||||
if (is_circular && q == oldhead)
|
||||
q = NULL;
|
||||
}
|
||||
|
||||
/* add the next element to the merged list */
|
||||
if (tail) {
|
||||
tail->next = e;
|
||||
} else {
|
||||
list = e;
|
||||
}
|
||||
if (is_double) {
|
||||
/*
|
||||
* Maintain reverse pointers in a
|
||||
* doubly linked list.
|
||||
*/
|
||||
e->prev = tail;
|
||||
}
|
||||
tail = e;
|
||||
}
|
||||
|
||||
/*
|
||||
* now p has stepped `insize' places along, and q has
|
||||
* too
|
||||
*/
|
||||
p = q;
|
||||
}
|
||||
if (is_circular) {
|
||||
tail->next = list;
|
||||
if (is_double)
|
||||
list->prev = tail;
|
||||
} else
|
||||
tail->next = NULL;
|
||||
|
||||
/* If we have done only one merge, we're finished. */
|
||||
if (nmerges <= 1) /* allow for nmerges==0, the empty
|
||||
* list case */
|
||||
return list;
|
||||
|
||||
/* Otherwise repeat, merging lists twice the size */
|
||||
insize *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TESTING
|
||||
int main()
|
||||
{
|
||||
JsonNode *n, *sorted, *arr = json_mkarray();
|
||||
JsonNode *o;
|
||||
|
||||
o = json_mkobject();
|
||||
json_append_member(o, "tst", json_mknumber(2));
|
||||
json_append_member(o, "desc", json_mkstring("dos"));
|
||||
json_append_element(arr, o);
|
||||
|
||||
o = json_mkobject();
|
||||
json_append_member(o, "tst", json_mknumber(69));
|
||||
json_append_member(o, "desc", json_mkstring("sixtynine"));
|
||||
json_append_element(arr, o);
|
||||
|
||||
o = json_mkobject();
|
||||
json_append_member(o, "tst", json_mknumber(14));
|
||||
json_append_member(o, "desc", json_mkstring("fourteen"));
|
||||
json_append_element(arr, o);
|
||||
|
||||
o = json_mkobject();
|
||||
json_append_member(o, "tst", json_mknumber(7));
|
||||
json_append_member(o, "desc", json_mkstring("seven"));
|
||||
json_append_element(arr, o);
|
||||
|
||||
|
||||
json_foreach(n, arr) {
|
||||
JsonNode *e = json_find_member(n, "tst");
|
||||
JsonNode *d = json_find_member(n, "desc");
|
||||
printf("%lf - %s\n", e->number_, d->string_);
|
||||
}
|
||||
|
||||
|
||||
listsort(NULL, 0, 0);
|
||||
sorted = listsort(json_first_child(arr), 0, 0);
|
||||
sorted = sorted->parent;
|
||||
printf("------- %s\n", (sorted == arr) ? "SAME" : "different");
|
||||
|
||||
json_foreach(n, sorted) {
|
||||
JsonNode *e = json_find_member(n, "tst");
|
||||
JsonNode *d = json_find_member(n, "desc");
|
||||
printf("%lf - %s\n", e->number_, d->string_);
|
||||
}
|
||||
|
||||
json_delete(arr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
8
listsort.h
Normal file
8
listsort.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef _LISTSORT_INCL_
|
||||
# define _LISTSORT_INCL_
|
||||
|
||||
#include "json.h"
|
||||
|
||||
JsonNode *listsort(JsonNode *list, int is_circular, int is_double);
|
||||
|
||||
#endif
|
||||
12
storage.c
12
storage.c
@@ -37,6 +37,7 @@
|
||||
#include "geohash.h"
|
||||
#include "util.h"
|
||||
#include "udata.h"
|
||||
#include "listsort.h"
|
||||
|
||||
char STORAGEDIR[BUFSIZ] = STORAGEDEFAULT;
|
||||
|
||||
@@ -852,12 +853,19 @@ JsonNode *geo_json(JsonNode *location_array)
|
||||
*/
|
||||
JsonNode *geo_linestring(JsonNode *location_array)
|
||||
{
|
||||
JsonNode *top = json_mkobject();
|
||||
JsonNode *top = json_mkobject(), *sorted;
|
||||
|
||||
json_append_member(top, "type", json_mkstring("Feature"));
|
||||
|
||||
JsonNode *c, *coords = json_mkarray();
|
||||
json_foreach(c, location_array) {
|
||||
|
||||
sorted = listsort(json_first_child(location_array), 0, 0);
|
||||
if (sorted && sorted->parent)
|
||||
sorted = sorted->parent;
|
||||
else
|
||||
sorted = location_array;
|
||||
|
||||
json_foreach(c, sorted) {
|
||||
JsonNode *lat, *lon;
|
||||
|
||||
if (((lat = json_find_member(c, "lat")) != NULL) &&
|
||||
|
||||
Reference in New Issue
Block a user