added opt-in refined error handling (not thread-safe!)

This commit is contained in:
poum 2019-04-04 11:08:47 +02:00
parent 9ed4e8f4da
commit 9711716922
3 changed files with 63 additions and 17 deletions

24
demo.c
View file

@ -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;
}

View file

@ -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;
}

View file

@ -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