From c29b474280a34175706d7c31df6051d499a90b65 Mon Sep 17 00:00:00 2001 From: Ari Jolma Date: Mon, 27 Sep 2021 14:29:40 +0300 Subject: [PATCH] WCS: Replace CompareNumbers with in-place numeric comparisons. (#4550) --- autotest/gdrivers/wcs.py | 40 ++++++++++++++++++++++++++++- gdal/frmts/wcs/wcsdataset201.cpp | 9 ++++--- gdal/frmts/wcs/wcsutils.cpp | 43 -------------------------------- gdal/frmts/wcs/wcsutils.h | 2 -- 4 files changed, 44 insertions(+), 50 deletions(-) diff --git a/autotest/gdrivers/wcs.py b/autotest/gdrivers/wcs.py index 9354099bc4d8..518185dc705f 100755 --- a/autotest/gdrivers/wcs.py +++ b/autotest/gdrivers/wcs.py @@ -242,6 +242,44 @@ def read_urls(): wcs_6_ok = True +def compare_urls(a, b): + """Compare two WCS URLs taking into account that some items are floats + """ + a_list = a.split('&') + b_list = b.split('&') + n = len(a_list) + if n != len(b_list): + return False + for i in (range(n)): + if not re.match('SUBSET=', a_list[i]): + if a_list[i] != b_list[i]: + print(a_list[i], '!=', b_list[i]) + return False + continue + x = a_list[i] + y = b_list[i] + for c in ('SUBSET=[a-zA-Z]+', '%28', '%29'): + x = re.sub(c, '', x) + y = re.sub(c, '', y) + x_list = x.split(',') + y_list = y.split(',') + m = len(x_list) + if m != len(y_list): + return False + for j in (range(m)): + try: + c1 = float(x_list[j]) + c2 = float(y_list[j]) + except Exception as e: + print(repr(e)) + return False + if c1 == c2: + continue + if abs((c1-c2)/c1) > 0.001: + return False + return True + + class WCSHTTPHandler(BaseHTTPRequestHandler): def log_request(self, code=',', size=','): @@ -313,7 +351,7 @@ def do_GET(self): got = re.sub(r'\&test=.*', '', got) _, have = urls[key][test].split('SERVICE=WCS') have += '&server=' + server - if got == have: + if compare_urls(got, have): ok = 'ok' else: ok = "not ok\ngot: " + got + "\nhave: " + have diff --git a/gdal/frmts/wcs/wcsdataset201.cpp b/gdal/frmts/wcs/wcsdataset201.cpp index 29a4a714f227..80b5828a78ce 100644 --- a/gdal/frmts/wcs/wcsdataset201.cpp +++ b/gdal/frmts/wcs/wcsdataset201.cpp @@ -32,6 +32,7 @@ #include "cpl_string.h" #include "cpl_minixml.h" #include "cpl_http.h" +#include "cpl_conv.h" #include "gmlutils.h" #include "gdal_frmts.h" #include "gdal_pam.h" @@ -182,11 +183,11 @@ CPLString WCSDataset201::GetCoverageRequest(bool scaled, std::vector low = Split(CPLGetXMLValue(psService, "Low", ""), ","); std::vector high = Split(CPLGetXMLValue(psService, "High", ""), ","); CPLString a = CPLString().Printf("%.17g", extent[0]); - if (low.size() > 1 && CompareNumbers(low[0], a) > 0) { + if (low.size() > 1 && CPLAtof(low[0].c_str()) > extent[0]) { a = low[0]; } CPLString b = CPLString().Printf("%.17g", extent[2]); - if (high.size() > 1 && CompareNumbers(high[0], b) < 0) { + if (high.size() > 1 && CPLAtof(high[0].c_str()) < extent[2]) { b = high[0]; } /* @@ -202,11 +203,11 @@ CPLString WCSDataset201::GetCoverageRequest(bool scaled, request += CPLString().Printf("&SUBSET=%s%%28%s,%s%%29", x, a.c_str(), b.c_str()); a = CPLString().Printf("%.17g", extent[1]); - if (low.size() > 1 && CompareNumbers(low[1], a) > 0) { + if (low.size() > 1 && CPLAtof(low[1].c_str()) > extent[1]) { a = low[1]; } b = CPLString().Printf("%.17g", extent[3]); - if (high.size() > 1 && CompareNumbers(high[1], b) < 0) { + if (high.size() > 1 && CPLAtof(high[1].c_str()) < extent[3]) { b = high[1]; } /* diff --git a/gdal/frmts/wcs/wcsutils.cpp b/gdal/frmts/wcs/wcsutils.cpp index 1aeb821adbee..6ba4b2a3f424 100644 --- a/gdal/frmts/wcs/wcsutils.cpp +++ b/gdal/frmts/wcs/wcsutils.cpp @@ -44,49 +44,6 @@ void Swap(double &a, double &b) b = tmp; } -int CompareNumbers(const std::string &a, const std::string &b) -{ - size_t a_dot = a.find("."); - size_t b_dot = b.find("."); - std::string a_p = a.substr(0, a_dot); - std::string b_p = b.substr(0, b_dot); - int d = (int)(a_p.length()) - (int)(b_p.length()); - if (d < 0) { - for (int i = 0; i < -1*d; ++i) { - a_p = "0" + a_p; - } - } else if (d > 0) { - for (int i = 0; i < d; ++i) { - b_p = "0" + b_p; - } - } - int c = a_p.compare(b_p); - if (c < 0) { - return -1; - } else if (c > 0) { - return 1; - } - a_p = a_dot == std::string::npos ? a : a.substr(a_dot + 1); - b_p = b_dot == std::string::npos ? b : b.substr(b_dot + 1); - d = (int)(a_p.length()) - (int)(b_p.length()); - if (d < 0) { - for (int i = 0; i < -1*d; ++i) { - a_p = a_p + "0"; - } - } else if (d > 0) { - for (int i = 0; i < d; ++i) { - b_p = b_p + "0"; - } - } - c = a_p.compare(b_p); - if (c < 0) { - return -1; - } else if (c > 0) { - return 1; - } - return 0; -} - CPLString URLEncode(const CPLString &str) { char *pszEncoded = CPLEscapeString(str, -1, CPLES_URL ); diff --git a/gdal/frmts/wcs/wcsutils.h b/gdal/frmts/wcs/wcsutils.h index b83c3c0a6756..8e85cd604170 100644 --- a/gdal/frmts/wcs/wcsutils.h +++ b/gdal/frmts/wcs/wcsutils.h @@ -37,8 +37,6 @@ namespace WCSUtils { void Swap(double &a, double &b); -int CompareNumbers(const std::string &a, const std::string &b); - CPLString URLEncode(const CPLString &str); CPLString URLRemoveKey(const char *url, const CPLString &key);