Add functions for opening a database from memory and a helper function that just returns the most important string from each database.

This commit is contained in:
Bertold Van den Bergh 2019-09-27 18:11:38 +02:00
parent 1c9f9917af
commit 1eb2a136e9
4 changed files with 163 additions and 44 deletions

14
demo.c
View file

@ -27,6 +27,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "zonedetect.h"
void printResults(ZoneDetect *cd, ZoneDetectResult *results, float safezone)
@ -73,6 +74,7 @@ void onError(int errZD, int errNative)
fprintf(stderr, "ZD error: %s (0x%08X)\n", ZDGetErrorString(errZD), (unsigned)errNative);
}
int main(int argc, char *argv[])
{
if(argc != 4) {
@ -82,7 +84,15 @@ int main(int argc, char *argv[])
ZDSetErrorHandler(onError);
ZoneDetect *const cd = ZDOpenDatabase(argv[1]);
uint8_t* data = malloc(128*1024*1024);
FILE* f= fopen(argv[1], "rb");
if(!f){ return 3; }
size_t bytes = fread(data, 1, 128*1024*1024, f);
fclose(f);
printf("Read %lu bytes\n", bytes);
//ZoneDetect *const cd = ZDOpenDatabase(argv[1]);
ZoneDetect *const cd = ZDOpenDatabaseFromMemory(data, bytes);
if(!cd) return 2;
const float lat = (float)atof(argv[2]);
@ -92,6 +102,8 @@ int main(int argc, char *argv[])
ZoneDetectResult *results = ZDLookup(cd, lat, lon, &safezone);
printResults(cd, results, safezone);
printf("The magic string is [%s]\n", ZDHelperLookupString(cd, lat, lon));
ZDCloseDatabase(cd);
return 0;

View file

@ -60,3 +60,11 @@ install:
cp zonedetect.h /usr/include/
cp $(EXECUTABLE) /usr/lib/
ldconfig
nice:
mkdir -p bak/
touch $(addsuffix .orig,$(INCLUDES_SRC))
touch $(addsuffix .orig,$(SOURCES_SRC))
astyle --style=k/r --indent=spaces=4 --indent-cases --indent-switches $(INCLUDES_SRC) $(SOURCES_SRC)
mv $(addsuffix .orig,$(INCLUDES_SRC)) bak/
mv $(addsuffix .orig,$(SOURCES_SRC)) bak/

View file

@ -68,6 +68,7 @@ struct ZoneDetectOpaque {
off_t length;
#endif
uint8_t closeType;
uint8_t *mapping;
uint8_t tableType;
@ -785,19 +786,51 @@ void ZDCloseDatabase(ZoneDetect *library)
free(library->notice);
}
if(library->closeType == 0) {
#if defined(_MSC_VER) || defined(__MINGW32__)
if(library->mapping && !UnmapViewOfFile(library->mapping)) zdError(ZD_E_DB_MUNMAP_MSVIEW, (int)GetLastError());
if(library->fdMap && !CloseHandle(library->fdMap)) zdError(ZD_E_DB_MUNMAP , (int)GetLastError());
if(library->fd && !CloseHandle(library->fd)) zdError(ZD_E_DB_CLOSE , (int)GetLastError());
if(library->mapping && !UnmapViewOfFile(library->mapping)) zdError(ZD_E_DB_MUNMAP_MSVIEW, (int)GetLastError());
if(library->fdMap && !CloseHandle(library->fdMap)) zdError(ZD_E_DB_MUNMAP, (int)GetLastError());
if(library->fd && !CloseHandle(library->fd)) zdError(ZD_E_DB_CLOSE, (int)GetLastError());
#else
if(library->mapping && munmap(library->mapping, (size_t)(library->length))) zdError(ZD_E_DB_MUNMAP, errno);
if(library->fd >= 0 && close(library->fd)) zdError(ZD_E_DB_CLOSE , errno);
if(library->mapping && munmap(library->mapping, (size_t)(library->length))) zdError(ZD_E_DB_MUNMAP, errno);
if(library->fd >= 0 && close(library->fd)) zdError(ZD_E_DB_CLOSE, errno);
#endif
}
free(library);
}
}
ZoneDetect *ZDOpenDatabaseFromMemory(void* buffer, size_t length)
{
ZoneDetect *const library = malloc(sizeof *library);
if(library) {
memset(library, 0, sizeof(*library));
library->closeType = 1;
library->length = (long int)length;
if(library->length <= 0) {
zdError(ZD_E_DB_SEEK, errno);
goto fail;
}
library->mapping = buffer;
/* Parse the header */
if(ZDParseHeader(library)) {
zdError(ZD_E_PARSE_HEADER, 0);
goto fail;
}
}
return library;
fail:
ZDCloseDatabase(library);
return NULL;
}
ZoneDetect *ZDOpenDatabase(const char *path)
{
ZoneDetect *const library = malloc(sizeof *library);
@ -1030,22 +1063,22 @@ uint8_t ZDGetTableType(const ZoneDetect *library)
const char *ZDLookupResultToString(ZDLookupResult result)
{
switch(result) {
case ZD_LOOKUP_IGNORE:
return "Ignore";
case ZD_LOOKUP_END:
return "End";
case ZD_LOOKUP_PARSE_ERROR:
return "Parsing error";
case ZD_LOOKUP_NOT_IN_ZONE:
return "Not in zone";
case ZD_LOOKUP_IN_ZONE:
return "In zone";
case ZD_LOOKUP_IN_EXCLUDED_ZONE:
return "In excluded zone";
case ZD_LOOKUP_ON_BORDER_VERTEX:
return "Target point is border vertex";
case ZD_LOOKUP_ON_BORDER_SEGMENT:
return "Target point is on border";
case ZD_LOOKUP_IGNORE:
return "Ignore";
case ZD_LOOKUP_END:
return "End";
case ZD_LOOKUP_PARSE_ERROR:
return "Parsing error";
case ZD_LOOKUP_NOT_IN_ZONE:
return "Not in zone";
case ZD_LOOKUP_IN_ZONE:
return "In zone";
case ZD_LOOKUP_IN_EXCLUDED_ZONE:
return "In excluded zone";
case ZD_LOOKUP_ON_BORDER_VERTEX:
return "Target point is border vertex";
case ZD_LOOKUP_ON_BORDER_SEGMENT:
return "Target point is on border";
}
return "Unknown";
@ -1056,30 +1089,30 @@ const char *ZDLookupResultToString(ZDLookupResult result)
const char *ZDGetErrorString(int errZD)
{
switch ((enum ZDInternalError)errZD) {
default:
assert(0);
case ZD_OK :
return "";
case ZD_E_DB_OPEN :
return ZD_E_COULD_NOT("open database file");
case ZD_E_DB_SEEK :
return ZD_E_COULD_NOT("retrieve database file size");
case ZD_E_DB_MMAP :
return ZD_E_COULD_NOT("map database file to system memory");
default:
assert(0);
case ZD_OK :
return "";
case ZD_E_DB_OPEN :
return ZD_E_COULD_NOT("open database file");
case ZD_E_DB_SEEK :
return ZD_E_COULD_NOT("retrieve database file size");
case ZD_E_DB_MMAP :
return ZD_E_COULD_NOT("map database file to system memory");
#if defined(_MSC_VER) || defined(__MINGW32__)
case ZD_E_DB_MMAP_MSVIEW :
return ZD_E_COULD_NOT("open database file view");
case ZD_E_DB_MAP_EXCEPTION:
return "I/O exception occurred while accessing database file view";
case ZD_E_DB_MUNMAP_MSVIEW:
return ZD_E_COULD_NOT("close database file view");
case ZD_E_DB_MMAP_MSVIEW :
return ZD_E_COULD_NOT("open database file view");
case ZD_E_DB_MAP_EXCEPTION:
return "I/O exception occurred while accessing database file view";
case ZD_E_DB_MUNMAP_MSVIEW:
return ZD_E_COULD_NOT("close database file view");
#endif
case ZD_E_DB_MUNMAP :
return ZD_E_COULD_NOT("unmap database");
case ZD_E_DB_CLOSE :
return ZD_E_COULD_NOT("close database file");
case ZD_E_PARSE_HEADER :
return ZD_E_COULD_NOT("parse database header");
case ZD_E_DB_MUNMAP :
return ZD_E_COULD_NOT("unmap database");
case ZD_E_DB_CLOSE :
return ZD_E_COULD_NOT("close database file");
case ZD_E_PARSE_HEADER :
return ZD_E_COULD_NOT("parse database header");
}
}
@ -1090,3 +1123,66 @@ int ZDSetErrorHandler(void (*handler)(int, int))
zdErrorHandler = handler;
return 0;
}
char* ZDHelperLookupString(const ZoneDetect* library, float lat, float lon)
{
ZoneDetectResult *result = ZDLookup(library, lat, lon, NULL);
if(!result) {
return NULL;
}
char* output = NULL;
if(result[0].lookupResult == ZD_LOOKUP_END) {
goto done;
}
char* strings[2] = {NULL};
for(unsigned int i = 0; i < result[0].numFields; i++) {
if(result[0].fieldNames[i] && result[0].data[i]) {
if(library->tableType == 'T') {
if(!strcmp(result[0].fieldNames[i], "TimezoneIdPrefix")) {
strings[0] = result[0].data[i];
}
if(!strcmp(result[0].fieldNames[i], "TimezoneId")) {
strings[1] = result[0].data[i];
}
}
if(library->tableType == 'C') {
if(!strcmp(result[0].fieldNames[i], "Name")) {
strings[0] = result[0].data[i];
}
}
}
}
size_t length = 0;
for(unsigned int i=0; i<sizeof(strings)/sizeof(char*); i++) {
if(strings[i]) {
size_t partLength = strlen(strings[i]);
if(partLength > 512) {
goto done;
}
length += partLength;
}
}
if(length == 0) {
goto done;
}
length += 1;
output = (char*)malloc(length);
output[0] = 0;
for(unsigned int i=0; i<sizeof(strings)/sizeof(char*); i++) {
if(strings[i]) {
strcat(output + strlen(output), strings[i]);
}
}
done:
ZDFreeResults(result);
return output;
}

View file

@ -67,6 +67,7 @@ extern "C" {
#endif
ZD_EXPORT ZoneDetect *ZDOpenDatabase(const char *path);
ZD_EXPORT ZoneDetect *ZDOpenDatabaseFromMemory(void* buffer, size_t length);
ZD_EXPORT void ZDCloseDatabase(ZoneDetect *library);
ZD_EXPORT ZoneDetectResult *ZDLookup(const ZoneDetect *library, float lat, float lon, float *safezone);
@ -81,6 +82,8 @@ ZD_EXPORT const char *ZDGetErrorString(int errZD);
ZD_EXPORT float* ZDPolygonToList(const ZoneDetect *library, uint32_t polygonId, size_t* length);
ZD_EXPORT char* ZDHelperLookupString(const ZoneDetect* library, float lat, float lon);
#ifdef __cplusplus
}
#endif