mirror of
https://github.com/BertoldVdb/ZoneDetect.git
synced 2026-03-25 08:45:56 +00:00
added opt-in refined error handling (not thread-safe!)
This commit is contained in:
parent
9ed4e8f4da
commit
9711716922
3 changed files with 63 additions and 17 deletions
24
demo.c
24
demo.c
|
|
@ -53,31 +53,33 @@ void printResults(ZoneDetectResult *results, float safezone)
|
|||
if(index) {
|
||||
printf("Safezone: %f\n", safezone);
|
||||
}
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
void onError(int errZD, int errNative)
|
||||
{
|
||||
fprintf(stderr, "ZD error: %s (0x%08X)\n", ZDGetErrorString(errZD), (unsigned)errNative);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
ZoneDetect *cd;
|
||||
if(argc != 4) {
|
||||
printf("Usage: %s dbname lat lon\n", argv[0]);
|
||||
exit(0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
cd = ZDOpenDatabase(argv[1]);
|
||||
if(!cd) {
|
||||
printf("Init failed\n");
|
||||
exit(0);
|
||||
}
|
||||
ZDSetErrorHandler(onError);
|
||||
|
||||
float lat = atof(argv[2]);
|
||||
float lon = atof(argv[3]);
|
||||
ZoneDetect *const cd = ZDOpenDatabase(argv[1]);
|
||||
if(!cd) return 2;
|
||||
|
||||
const float lat = (float)atof(argv[2]);
|
||||
const float lon = (float)atof(argv[3]);
|
||||
|
||||
float safezone = 0;
|
||||
ZoneDetectResult *results = ZDLookup(cd, lat, lon, &safezone);
|
||||
printResults(results, safezone);
|
||||
|
||||
ZDCloseDatabase(cd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
*/
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -36,6 +38,16 @@
|
|||
|
||||
#include "zonedetect.h"
|
||||
|
||||
enum ZDInternalError {
|
||||
ZD_OK,
|
||||
ZD_E_DB_OPEN,
|
||||
ZD_E_DB_SEEK,
|
||||
ZD_E_DB_MMAP,
|
||||
ZD_E_DB_MUNMAP,
|
||||
ZD_E_DB_CLOSE,
|
||||
ZD_E_PARSE_HEADER
|
||||
};
|
||||
|
||||
struct ZoneDetectOpaque {
|
||||
int fd;
|
||||
off_t length;
|
||||
|
|
@ -54,6 +66,12 @@ struct ZoneDetectOpaque {
|
|||
uint32_t dataOffset;
|
||||
};
|
||||
|
||||
static void (*zdErrorHandler)(int, int);
|
||||
static void zdError(enum ZDInternalError errZD, int errNative)
|
||||
{
|
||||
if (zdErrorHandler) zdErrorHandler((int)errZD, errNative);
|
||||
}
|
||||
|
||||
static int32_t ZDFloatToFixedPoint(float input, float scale, unsigned int precision)
|
||||
{
|
||||
const float inputScaled = input / scale;
|
||||
|
|
@ -373,12 +391,8 @@ void ZDCloseDatabase(ZoneDetect *library)
|
|||
if(library->notice) {
|
||||
free(library->notice);
|
||||
}
|
||||
if(library->mapping) {
|
||||
munmap(library->mapping, (size_t)(library->length));
|
||||
}
|
||||
if(library->fd >= 0) {
|
||||
close(library->fd);
|
||||
}
|
||||
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);
|
||||
free(library);
|
||||
}
|
||||
}
|
||||
|
|
@ -392,22 +406,26 @@ ZoneDetect *ZDOpenDatabase(const char *path)
|
|||
|
||||
library->fd = open(path, O_RDONLY | O_CLOEXEC);
|
||||
if(library->fd < 0) {
|
||||
zdError(ZD_E_DB_OPEN, errno);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
library->length = lseek(library->fd, 0, SEEK_END);
|
||||
if(library->length <= 0) {
|
||||
zdError(ZD_E_DB_SEEK, errno);
|
||||
goto fail;
|
||||
}
|
||||
lseek(library->fd, 0, SEEK_SET);
|
||||
|
||||
library->mapping = mmap(NULL, (size_t)library->length, PROT_READ, MAP_PRIVATE | MAP_FILE, library->fd, 0);
|
||||
if(!library->mapping) {
|
||||
zdError(ZD_E_DB_MMAP, errno);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Parse the header */
|
||||
if(ZDParseHeader(library)) {
|
||||
zdError(ZD_E_PARSE_HEADER, 0);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
|
@ -604,3 +622,26 @@ const char *ZDLookupResultToString(ZDLookupResult result)
|
|||
return "Unknown";
|
||||
}
|
||||
|
||||
#define ZD_E_COULD_NOT(msg) "could not " msg
|
||||
|
||||
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");
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
#undef ZD_E_COULD_NOT
|
||||
|
||||
int ZDSetErrorHandler(void (*handler)(int, int))
|
||||
{
|
||||
zdErrorHandler = handler;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,6 +67,9 @@ const char *ZDGetNotice(const ZoneDetect *library);
|
|||
uint8_t ZDGetTableType(const ZoneDetect *library);
|
||||
const char *ZDLookupResultToString(ZDLookupResult result);
|
||||
|
||||
int ZDSetErrorHandler(void (*handler)(int, int));
|
||||
const char *ZDGetErrorString(int error);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue