Convert ImageLoaderBackend to interface and backends to implementations
[geeqie.git] / src / zonedetect.cc
index 696193b..51bed5c 100644 (file)
@@ -33,6 +33,9 @@
 #include <windows.h>
 #elif defined(__APPLE__) || defined(__linux__) || defined(__unix__) || defined(_POSIX_VERSION)
 #include <cerrno>
+#include <memory>
+#include <vector>
+
 #include <fcntl.h>
 #include <sys/mman.h>
 #include <unistd.h>
@@ -119,7 +122,7 @@ static unsigned int ZDDecodeVariableLengthUnsigned(const ZoneDetect *library, ui
         unsigned int shift = 0;
         while(true) {
             value |= (((static_cast<uint64_t>(buffer[i])) & UINT8_C(0x7F)) << shift);
-            shift += 7u;
+            shift += 7U;
 
             if(!(buffer[i] & UINT8_C(0x80))) {
                 break;
@@ -262,7 +265,7 @@ static int ZDParseHeader(ZoneDetect *library)
 #if defined(_MSC_VER)
     __try {
 #endif
-        if(memcmp(library->mapping, "PLB", 3)) {
+        if(memcmp(library->mapping, "PLB", 3) != 0) {
             return -1;
         }
 
@@ -338,12 +341,12 @@ static int ZDPointInBox(int32_t xl, int32_t x, int32_t xr, int32_t yl, int32_t y
 
 static uint32_t ZDUnshuffle(uint64_t w)
 {
-    w &=                  0x5555555555555555llu;
-    w = (w | (w >> 1))  & 0x3333333333333333llu;
-    w = (w | (w >> 2))  & 0x0F0F0F0F0F0F0F0Fllu;
-    w = (w | (w >> 4))  & 0x00FF00FF00FF00FFllu;
-    w = (w | (w >> 8))  & 0x0000FFFF0000FFFFllu;
-    w = (w | (w >> 16)) & 0x00000000FFFFFFFFllu;
+    w &=                  0x5555555555555555LLU;
+    w = (w | (w >> 1))  & 0x3333333333333333LLU;
+    w = (w | (w >> 2))  & 0x0F0F0F0F0F0F0F0FLLU;
+    w = (w | (w >> 4))  & 0x00FF00FF00FF00FFLLU;
+    w = (w | (w >> 8))  & 0x0000FFFF0000FFFFLLU;
+    w = (w | (w >> 16)) & 0x00000000FFFFFFFFLLU;
     return static_cast<uint32_t>(w);
 }
 
@@ -379,109 +382,113 @@ static void ZDReaderInit(struct Reader *reader, const ZoneDetect *library, uint3
 
 static int ZDReaderGetPoint(struct Reader *reader, int32_t *pointLat, int32_t *pointLon)
 {
-    int32_t diffLat = 0, diffLon = 0;
+    int32_t diffLat = 0;
+    int32_t diffLon = 0;
 
-readNewPoint:
-    if(reader->done > 1) {
-        return 0;
-    }
+    while(true) {
+        if(reader->done > 1) {
+            return 0;
+        }
 
-    if(reader->first && reader->library->version == 0) {
-        if(!ZDDecodeVariableLengthUnsigned(reader->library, &reader->polygonIndex, &reader->numVertices)) return -1;
-        if(!reader->numVertices) return -1;
-    }
+        if(reader->first && reader->library->version == 0) {
+            if(!ZDDecodeVariableLengthUnsigned(reader->library, &reader->polygonIndex, &reader->numVertices)) return -1;
+            if(!reader->numVertices) return -1;
+        }
 
-    uint8_t referenceDone = 0;
+        uint8_t referenceDone = 0;
 
-    if(reader->library->version == 1) {
-        uint64_t point = 0;
+        if(reader->library->version == 1) {
+            uint64_t point = 0;
 
-        if(!reader->referenceDirection) {
-            if(!ZDDecodeVariableLengthUnsigned(reader->library, &reader->polygonIndex, &point)) return -1;
-        } else {
-            if(reader->referenceDirection > 0) {
-                /* Read reference forward */
-                if(!ZDDecodeVariableLengthUnsigned(reader->library, &reader->referenceStart, &point)) return -1;
-                if(reader->referenceStart >= reader->referenceEnd) {
-                    referenceDone = 1;
-                }
-            } else if(reader->referenceDirection < 0) {
-                /* Read reference backwards */
-                if(!ZDDecodeVariableLengthUnsignedReverse(reader->library, &reader->referenceStart, &point)) return -1;
-                if(reader->referenceStart <= reader->referenceEnd) {
-                    referenceDone = 1;
+            if(!reader->referenceDirection) {
+                if(!ZDDecodeVariableLengthUnsigned(reader->library, &reader->polygonIndex, &point)) return -1;
+            } else {
+                if(reader->referenceDirection > 0) {
+                    /* Read reference forward */
+                    if(!ZDDecodeVariableLengthUnsigned(reader->library, &reader->referenceStart, &point)) return -1;
+                    if(reader->referenceStart >= reader->referenceEnd) {
+                        referenceDone = 1;
+                    }
+                } else if(reader->referenceDirection < 0) {
+                    /* Read reference backwards */
+                    if(!ZDDecodeVariableLengthUnsignedReverse(reader->library, &reader->referenceStart, &point)) return -1;
+                    if(reader->referenceStart <= reader->referenceEnd) {
+                        referenceDone = 1;
+                    }
                 }
             }
-        }
 
-        if(!point) {
-            /* This is a special marker, it is not allowed in reference mode */
-            if(reader->referenceDirection) {
-                return -1;
-            }
+            if(!point) {
+                /* This is a special marker, it is not allowed in reference mode */
+                if(reader->referenceDirection) {
+                    return -1;
+                }
 
-            uint64_t value;
-            if(!ZDDecodeVariableLengthUnsigned(reader->library, &reader->polygonIndex, &value)) return -1;
-
-            if(value == 0) {
-                reader->done = 2;
-            } else if(value == 1) {
-                int32_t diff;
-                int64_t start;
-                if(!ZDDecodeVariableLengthUnsigned(reader->library, &reader->polygonIndex, reinterpret_cast<uint64_t*>(&start))) return -1;
-                if(!ZDDecodeVariableLengthSigned(reader->library, &reader->polygonIndex, &diff)) return -1;
-
-                reader->referenceStart = reader->library->dataOffset+static_cast<uint32_t>(start);
-                reader->referenceEnd = reader->library->dataOffset+static_cast<uint32_t>(start + diff);
-                reader->referenceDirection = diff;
-                if(diff < 0) {
-                    reader->referenceStart--;
-                    reader->referenceEnd--;
+                uint64_t value;
+                if(!ZDDecodeVariableLengthUnsigned(reader->library, &reader->polygonIndex, &value)) return -1;
+
+                if(value == 0) {
+                    reader->done = 2;
+                } else if(value == 1) {
+                    int32_t diff;
+                    int64_t start;
+                    if(!ZDDecodeVariableLengthUnsigned(reader->library, &reader->polygonIndex, reinterpret_cast<uint64_t*>(&start))) return -1;
+                    if(!ZDDecodeVariableLengthSigned(reader->library, &reader->polygonIndex, &diff)) return -1;
+
+                    reader->referenceStart = reader->library->dataOffset+static_cast<uint32_t>(start);
+                    reader->referenceEnd = reader->library->dataOffset+static_cast<uint32_t>(start + diff);
+                    reader->referenceDirection = diff;
+                    if(diff < 0) {
+                        reader->referenceStart--;
+                        reader->referenceEnd--;
+                    }
+                    continue;
+                }
+            } else {
+                ZDDecodePoint(point, &diffLat, &diffLon);
+                if(reader->referenceDirection < 0) {
+                    diffLat = -diffLat;
+                    diffLon = -diffLon;
                 }
-                goto readNewPoint;
-            }
-        } else {
-            ZDDecodePoint(point, &diffLat, &diffLon);
-            if(reader->referenceDirection < 0) {
-                diffLat = -diffLat;
-                diffLon = -diffLon;
             }
         }
-    }
 
-    if(reader->library->version == 0) {
-        if(!ZDDecodeVariableLengthSigned(reader->library, &reader->polygonIndex, &diffLat)) return -1;
-        if(!ZDDecodeVariableLengthSigned(reader->library, &reader->polygonIndex, &diffLon)) return -1;
-    }
+        if(reader->library->version == 0) {
+            if(!ZDDecodeVariableLengthSigned(reader->library, &reader->polygonIndex, &diffLat)) return -1;
+            if(!ZDDecodeVariableLengthSigned(reader->library, &reader->polygonIndex, &diffLon)) return -1;
+        }
 
-    if(!reader->done) {
-        reader->pointLat += diffLat;
-        reader->pointLon += diffLon;
-        if(reader->first) {
-            reader->firstLat = reader->pointLat;
-            reader->firstLon = reader->pointLon;
+        if(!reader->done) {
+            reader->pointLat += diffLat;
+            reader->pointLon += diffLon;
+            if(reader->first) {
+                reader->firstLat = reader->pointLat;
+                reader->firstLon = reader->pointLon;
+            }
+        } else {
+            /* Close the polygon (the closing point is not encoded) */
+            reader->pointLat = reader->firstLat;
+            reader->pointLon = reader->firstLon;
+            reader->done = 2;
         }
-    } else {
-        /* Close the polygon (the closing point is not encoded) */
-        reader->pointLat = reader->firstLat;
-        reader->pointLon = reader->firstLon;
-        reader->done = 2;
-    }
 
-    reader->first = 0;
+        reader->first = 0;
 
-    if(reader->library->version == 0) {
-        reader->numVertices--;
-        if(!reader->numVertices) {
-            reader->done = 1;
+        if(reader->library->version == 0) {
+            reader->numVertices--;
+            if(!reader->numVertices) {
+                reader->done = 1;
+            }
+            if(!diffLat && !diffLon) {
+                continue;
+            }
         }
-        if(!diffLat && !diffLon) {
-            goto readNewPoint;
+
+        if(referenceDone) {
+            reader->referenceDirection = 0;
         }
-    }
 
-    if(referenceDone) {
-        reader->referenceDirection = 0;
+        break;
     }
 
     if(pointLat) {
@@ -500,7 +507,8 @@ static int ZDFindPolygon(const ZoneDetect *library, uint32_t wantedId, uint32_t*
     uint32_t polygonId = 0;
     uint32_t bboxIndex = library->bboxOffset;
 
-    uint32_t metadataIndex = 0, polygonIndex = 0;
+    uint32_t metadataIndex = 0;
+    uint32_t polygonIndex = 0;
 
     while(bboxIndex < library->metadataOffset) {
         uint64_t polygonIndexDelta;
@@ -534,76 +542,55 @@ static int ZDFindPolygon(const ZoneDetect *library, uint32_t wantedId, uint32_t*
     return 0;
 }
 
-static int32_t* ZDPolygonToListInternal(const ZoneDetect *library, uint32_t polygonIndex, size_t* length)
+static std::vector<int32_t> ZDPolygonToListInternal(const ZoneDetect *library, uint32_t polygonIndex)
 {
     struct Reader reader;
     ZDReaderInit(&reader, library, polygonIndex);
 
-    size_t listLength = 2 * 100;
-    size_t listIndex = 0;
-
-    auto list = static_cast<int32_t *>(malloc(sizeof(int32_t) * listLength));
-    if(!list) {
-        goto fail;
-    }
+    constexpr size_t listLength = 2 * 100;
+    std::vector<int32_t> list;
+    list.reserve(listLength);
 
     while(true) {
-        int32_t pointLat, pointLon;
+        int32_t pointLat;
+        int32_t pointLon;
         int result = ZDReaderGetPoint(&reader, &pointLat, &pointLon);
         if(result < 0) {
-            goto fail;
-        } else if(result == 0) {
+            return {};
+        }
+        if(result == 0) {
             break;
         }
 
-        if(listIndex >= listLength) {
-            listLength *= 2;
-            if(listLength >= 1048576) {
-                goto fail;
-            }
+        list.push_back(pointLat);
+        list.push_back(pointLon);
 
-            list = static_cast<int32_t *>(realloc(list, sizeof(int32_t) * listLength));
-            if(!list) {
-                goto fail;
-            }
+        if(list.size() >= 1048576) {
+            return {};
         }
-
-        list[listIndex++] = pointLat;
-        list[listIndex++] = pointLon;
-    }
-
-    if(length) {
-        *length = listIndex;
     }
 
     return list;
-
-fail:
-    if(list) {
-        free(list);
-    }
-    return nullptr;
 }
 
 float* ZDPolygonToList(const ZoneDetect *library, uint32_t polygonId, size_t* lengthPtr)
 {
     uint32_t polygonIndex;
-    int32_t* data = nullptr;
     float* flData = nullptr;
-    size_t length = 0;
 
     if (!ZDFindPolygon(library, polygonId, nullptr, &polygonIndex))
-           return nullptr;
+        return nullptr;
+
+    const auto data = ZDPolygonToListInternal(library, polygonIndex);
+    if (data.empty())
+        return nullptr;
 
-    data = ZDPolygonToListInternal(library, polygonIndex, &length);
-    if (!data)
-           return nullptr;
+    size_t length = data.size();
 
     flData = static_cast<float *>(malloc(sizeof(float) * length));
     if(!flData) {
-           free(data);
-           return nullptr;
-           }
+        return nullptr;
+    }
 
     for(size_t i = 0; i<length; i+= 2) {
         int32_t lat = data[i];
@@ -613,8 +600,6 @@ float* ZDPolygonToList(const ZoneDetect *library, uint32_t polygonId, size_t* le
         flData[i+1] = ZDFixedPointToFloat(lon, 180, library->precision);
     }
 
-    free(data);
-
     if(lengthPtr) {
         *lengthPtr = length;
     }
@@ -624,8 +609,12 @@ float* ZDPolygonToList(const ZoneDetect *library, uint32_t polygonId, size_t* le
 
 static ZDLookupResult ZDPointInPolygon(const ZoneDetect *library, uint32_t polygonIndex, int32_t latFixedPoint, int32_t lonFixedPoint, uint64_t *distanceSqrMin)
 {
-    int32_t pointLat, pointLon, prevLat = 0, prevLon = 0;
-    int prevQuadrant = 0, winding = 0;
+    int32_t pointLat;
+    int32_t pointLon;
+    int32_t prevLat = 0;
+    int32_t prevLon = 0;
+    int prevQuadrant = 0;
+    int winding = 0;
 
     uint8_t first = 1;
 
@@ -636,7 +625,7 @@ static ZDLookupResult ZDPointInPolygon(const ZoneDetect *library, uint32_t polyg
         int result = ZDReaderGetPoint(&reader, &pointLat, &pointLon);
         if(result < 0) {
             return ZD_LOOKUP_PARSE_ERROR;
-        } else if(result == 0) {
+        } if(result == 0) {
             break;
         }
 
@@ -663,8 +652,10 @@ static ZDLookupResult ZDPointInPolygon(const ZoneDetect *library, uint32_t polyg
         }
 
         if(!first) {
-            int windingNeedCompare = 0, lineIsStraight = 0;
-            float a = 0, b = 0;
+            int windingNeedCompare = 0;
+            int lineIsStraight = 0;
+            float a = 0;
+            float b = 0;
 
             /* Calculate winding number */
             if(quadrant == prevQuadrant) {
@@ -714,7 +705,8 @@ static ZDLookupResult ZDPointInPolygon(const ZoneDetect *library, uint32_t polyg
 
             /* Calculate closest point on line (if needed) */
             if(distanceSqrMin) {
-                float closestLon, closestLat;
+                float closestLon;
+                float closestLat;
                 if(!lineIsStraight) {
                     closestLon = (static_cast<float>(lonFixedPoint) + a * static_cast<float>(latFixedPoint) - a * b) / (a * a + 1);
                     closestLat = (a * (static_cast<float>(lonFixedPoint) + a * static_cast<float>(latFixedPoint)) + b) / (a * a + 1);
@@ -730,7 +722,8 @@ static ZDLookupResult ZDPointInPolygon(const ZoneDetect *library, uint32_t polyg
 
                 const int closestInBox = ZDPointInBox(pointLon, static_cast<int32_t>(closestLon), prevLon, pointLat, static_cast<int32_t>(closestLat), prevLat);
 
-                int64_t diffLat, diffLon;
+                int64_t diffLat;
+                int64_t diffLon;
                 if(closestInBox) {
                     /* Calculate squared distance to segment. */
                     diffLat = static_cast<int64_t>(closestLat - static_cast<float>(latFixedPoint));
@@ -758,9 +751,9 @@ static ZDLookupResult ZDPointInPolygon(const ZoneDetect *library, uint32_t polyg
 
     if(winding == -4) {
         return ZD_LOOKUP_IN_ZONE;
-    } else if(winding == 4) {
+    } if(winding == 4) {
         return ZD_LOOKUP_IN_EXCLUDED_ZONE;
-    } else if(winding == 0) {
+    } if(winding == 0) {
         return ZD_LOOKUP_NOT_IN_ZONE;
     }
 
@@ -800,12 +793,20 @@ void ZDCloseDatabase(ZoneDetect *library)
     }
 }
 
+struct ZoneDetectDeleter {
+    void operator()(ZoneDetect *library)
+    {
+        ZDCloseDatabase(library);
+    }
+};
+
+using ZoneDetectPtr = std::unique_ptr<ZoneDetect, ZoneDetectDeleter>;
+
 ZoneDetect *ZDOpenDatabaseFromMemory(void* buffer, size_t length)
 {
-    auto library = static_cast<ZoneDetect *>(malloc(sizeof(ZoneDetect)));
+    ZoneDetectPtr library{static_cast<ZoneDetect *>(calloc(1, sizeof(ZoneDetect)))};
 
     if(library) {
-        memset(library, 0, sizeof(*library));
         library->closeType = 1;
         library->length = static_cast<long int>(length);
 
@@ -815,90 +816,80 @@ ZoneDetect *ZDOpenDatabaseFromMemory(void* buffer, size_t length)
 #else
             zdError(ZD_E_DB_SEEK, 0);
 #endif
-            goto fail;
+            return nullptr;
         }
 
         library->mapping = static_cast<uint8_t *>(buffer);
 
         /* Parse the header */
-        if(ZDParseHeader(library)) {
+        if(ZDParseHeader(library.get())) {
             zdError(ZD_E_PARSE_HEADER, 0);
-            goto fail;
+            return nullptr;
         }
     }
 
-    return library;
-
-fail:
-    ZDCloseDatabase(library);
-    return nullptr;
+    return library.release();
 }
 
 ZoneDetect *ZDOpenDatabase(const char *path)
 {
-    auto library = static_cast<ZoneDetect *>(malloc(sizeof(ZoneDetect)));
+    ZoneDetectPtr library{static_cast<ZoneDetect *>(calloc(1, sizeof(ZoneDetect)))};
 
     if(library) {
-        memset(library, 0, sizeof(*library));
-
 #if defined(_MSC_VER) || defined(__MINGW32__)
         library->fd = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
         if (library->fd == INVALID_HANDLE_VALUE) {
             zdError(ZD_E_DB_OPEN, (int)GetLastError());
-            goto fail;
+            return nullptr;
         }
 
         const DWORD fsize = GetFileSize(library->fd, NULL);
         if (fsize == INVALID_FILE_SIZE) {
             zdError(ZD_E_DB_SEEK, (int)GetLastError());
-            goto fail;
+            return nullptr;
         }
         library->length = (int32_t)fsize;
 
         library->fdMap = CreateFileMappingA(library->fd, NULL, PAGE_READONLY, 0, 0, NULL);
         if (!library->fdMap) {
             zdError(ZD_E_DB_MMAP, (int)GetLastError());
-            goto fail;
+            return nullptr;
         }
 
         library->mapping = MapViewOfFile(library->fdMap, FILE_MAP_READ, 0, 0, 0);
         if (!library->mapping) {
             zdError(ZD_E_DB_MMAP_MSVIEW, (int)GetLastError());
-            goto fail;
+            return nullptr;
         }
 #elif defined(__APPLE__) || defined(__linux__) || defined(__unix__) || defined(_POSIX_VERSION)
         library->fd = open(path, O_RDONLY | O_CLOEXEC);
         if(library->fd < 0) {
             zdError(ZD_E_DB_OPEN, errno);
-            goto fail;
+            return nullptr;
         }
 
         library->length = lseek(library->fd, 0, SEEK_END);
         if(library->length <= 0 || library->length > 50331648) {
             zdError(ZD_E_DB_SEEK, errno);
-            goto fail;
+            return nullptr;
         }
         lseek(library->fd, 0, SEEK_SET);
 
         library->mapping = static_cast<uint8_t *>(mmap(nullptr, static_cast<size_t>(library->length), PROT_READ, MAP_PRIVATE | MAP_FILE, library->fd, 0));
         if(library->mapping == MAP_FAILED) {
             zdError(ZD_E_DB_MMAP, errno);
-            goto fail;
+            return nullptr;
         }
 #endif
 
         /* Parse the header */
-        if(ZDParseHeader(library)) {
+        if(ZDParseHeader(library.get())) {
             zdError(ZD_E_PARSE_HEADER, 0);
-            goto fail;
+            return nullptr;
         }
     }
 
-    return library;
-
-fail:
-    ZDCloseDatabase(library);
-    return nullptr;
+    return library.release();
 }
 
 ZoneDetectResult *ZDLookup(const ZoneDetect *library, float lat, float lon, float *safezone)
@@ -921,7 +912,11 @@ ZoneDetectResult *ZDLookup(const ZoneDetect *library, float lat, float lon, floa
     uint32_t polygonId = 0;
 
     while(bboxIndex < library->metadataOffset) {
-        int32_t minLat, minLon, maxLat, maxLon, metadataIndexDelta;
+        int32_t minLat;
+        int32_t minLon;
+        int32_t maxLat;
+        int32_t maxLon;
+        int32_t metadataIndexDelta;
         uint64_t polygonIndexDelta;
         if(!ZDDecodeVariableLengthSigned(library, &bboxIndex, &minLat)) break;
         if(!ZDDecodeVariableLengthSigned(library, &bboxIndex, &minLon)) break;
@@ -941,7 +936,7 @@ ZoneDetectResult *ZDLookup(const ZoneDetect *library, float lat, float lon, floa
                 const ZDLookupResult lookupResult = ZDPointInPolygon(library, library->dataOffset + polygonIndex, latFixedPoint, lonFixedPoint, (safezone) ? &distanceSqrMin : nullptr);
                 if(lookupResult == ZD_LOOKUP_PARSE_ERROR) {
                     break;
-                } else if(lookupResult != ZD_LOOKUP_NOT_IN_ZONE) {
+                } if(lookupResult != ZD_LOOKUP_NOT_IN_ZONE) {
                     auto newResults = static_cast<ZoneDetectResult *>(realloc(results, sizeof(ZoneDetectResult) * (numResults + 2)));
 
                     if(newResults) {
@@ -1173,7 +1168,7 @@ int ZDSetErrorHandler(void (*handler)(int, int))
 
 char* ZDHelperSimpleLookupString(const ZoneDetect* library, float lat, float lon)
 {
-    ZoneDetectResult *result = ZDLookup(library, lat, lon, nullptr);
+    std::unique_ptr<ZoneDetectResult, decltype(&ZDFreeResults)> result{ZDLookup(library, lat, lon, nullptr), ZDFreeResults};
     if(!result) {
         return nullptr;
     }
@@ -1182,23 +1177,23 @@ char* ZDHelperSimpleLookupString(const ZoneDetect* library, float lat, float lon
     size_t length = 0;
     char* strings[2] = {nullptr};
 
-    if(result[0].lookupResult == ZD_LOOKUP_END) {
-        goto done;
+    if(result->lookupResult == ZD_LOOKUP_END) {
+        return nullptr;
     }
 
-    for(int i = 0; i < result[0].numFields; i++) {
-        if(result[0].fieldNames[i] && result[0].data[i]) {
+    for(int i = 0; i < result->numFields; i++) {
+        if(result->fieldNames[i] && result->data[i]) {
             if(library->tableType == 'T') {
-                if(!strcmp(result[0].fieldNames[i], "TimezoneIdPrefix")) {
-                    strings[0] = result[0].data[i];
+                if(!strcmp(result->fieldNames[i], "TimezoneIdPrefix")) {
+                    strings[0] = result->data[i];
                 }
-                if(!strcmp(result[0].fieldNames[i], "TimezoneId")) {
-                    strings[1] = result[0].data[i];
+                if(!strcmp(result->fieldNames[i], "TimezoneId")) {
+                    strings[1] = result->data[i];
                 }
             }
             if(library->tableType == 'C') {
-                if(!strcmp(result[0].fieldNames[i], "Name")) {
-                    strings[0] = result[0].data[i];
+                if(!strcmp(result->fieldNames[i], "Name")) {
+                    strings[0] = result->data[i];
                 }
             }
         }
@@ -1208,14 +1203,14 @@ char* ZDHelperSimpleLookupString(const ZoneDetect* library, float lat, float lon
         if(string) {
             size_t partLength = strlen(string);
             if(partLength > 512) {
-                goto done;
+                return nullptr;
             }
             length += partLength;
         }
     }
 
     if(length == 0) {
-        goto done;
+        return nullptr;
     }
 
     length += 1;
@@ -1230,7 +1225,5 @@ char* ZDHelperSimpleLookupString(const ZoneDetect* library, float lat, float lon
         }
     }
 
-done:
-    ZDFreeResults(result);
     return output;
 }