kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

commit 439a3b36f02a1a96d22d127793192cf39a14b15b
parent b7669f49f76a37b62846237aa326ada415923151
Author: Joris Vink <joris@coders.se>
Date:   Fri,  4 May 2018 15:55:35 +0200

Add kore_strtodouble().

Use it for http_argument_get_float() and http_argument_get_double().

Diffstat:
examples/integers/conf/integers.conf | 2+-
examples/integers/src/check_integers.c | 10++++++++++
include/kore/http.h | 17+++++++++++++++++
include/kore/kore.h | 1+
src/http.c | 7+++++++
src/utils.c | 32++++++++++++++++++++++++++++++++
6 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/examples/integers/conf/integers.conf b/examples/integers/conf/integers.conf @@ -8,7 +8,7 @@ worker_max_connections 5000 tls_dhparam dh2048.pem -validator v_id regex ^-?[0-9]*$ +validator v_id regex ^-?[0-9]*.?[0-9]+$ domain * { certfile cert/server.pem diff --git a/examples/integers/src/check_integers.c b/examples/integers/src/check_integers.c @@ -1,11 +1,15 @@ #include <kore/kore.h> #include <kore/http.h> +#include <float.h> + int page(struct http_request *); int page(struct http_request *req) { + float fl; + double dbl; int16_t s16; u_int16_t u16; int32_t s32; @@ -40,6 +44,12 @@ page(struct http_request *req) if (http_argument_get_uint64(req, "id", &u64)) kore_buf_appendf(buf, "uint64\t%lu\n", u64); + if (http_argument_get_float(req, "id", &fl)) + kore_buf_appendf(buf, "float\t%g\n", fl); + + if (http_argument_get_double(req, "id", &dbl)) + kore_buf_appendf(buf, "double\t%g\n", dbl); + data = kore_buf_release(buf, &len); http_response(req, 200, data, len); kore_free(data); diff --git a/include/kore/http.h b/include/kore/http.h @@ -58,6 +58,8 @@ extern "C" { #define HTTP_ARG_TYPE_STRING 6 #define HTTP_ARG_TYPE_INT64 7 #define HTTP_ARG_TYPE_UINT64 8 +#define HTTP_ARG_TYPE_FLOAT 9 +#define HTTP_ARG_TYPE_DOUBLE 10 #define HTTP_STATE_ERROR 0 #define HTTP_STATE_CONTINUE 1 @@ -108,6 +110,16 @@ struct http_arg { COPY_ARG_TYPE(nval, type); \ } while (0) +#define COPY_ARG_DOUBLE(min, max, type) \ + do { \ + int err; \ + type nval; \ + nval = kore_strtodouble(q->s_value, min, max, &err); \ + if (err != KORE_RESULT_OK) \ + return (KORE_RESULT_ERROR); \ + COPY_ARG_TYPE(nval, type); \ + } while (0) + #define COPY_ARG_INT(min, max, type) \ do { \ int err; \ @@ -159,6 +171,11 @@ struct http_arg { #define http_argument_get_int64(r, n, o) \ http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_INT64) +#define http_argument_get_float(r, n, o) \ + http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_FLOAT) + +#define http_argument_get_double(r, n, o) \ + http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_DOUBLE) struct http_file { char *name; diff --git a/include/kore/kore.h b/include/kore/kore.h @@ -587,6 +587,7 @@ int kore_split_string(char *, const char *, char **, size_t); void kore_strip_chars(char *, const char, char **); int kore_snprintf(char *, size_t, int *, const char *, ...); long long kore_strtonum(const char *, int, long long, long long, int *); +double kore_strtodouble(const char *, long double, long double, int *); int kore_base64_encode(const void *, size_t, char **); int kore_base64_decode(const char *, u_int8_t **, size_t *); void *kore_mem_find(void *, size_t, void *, size_t); diff --git a/src/http.c b/src/http.c @@ -22,6 +22,7 @@ #include <ctype.h> #include <fcntl.h> #include <inttypes.h> +#include <float.h> #include <time.h> #include <stdio.h> #include <string.h> @@ -735,6 +736,12 @@ http_argument_get(struct http_request *req, const char *name, case HTTP_ARG_TYPE_UINT64: COPY_AS_INTTYPE_64(u_int64_t, 0); return (KORE_RESULT_OK); + case HTTP_ARG_TYPE_FLOAT: + COPY_ARG_DOUBLE(-FLT_MAX, FLT_MAX, float); + return (KORE_RESULT_OK); + case HTTP_ARG_TYPE_DOUBLE: + COPY_ARG_DOUBLE(-DBL_MAX, DBL_MAX, double); + return (KORE_RESULT_OK); case HTTP_ARG_TYPE_STRING: *out = q->s_value; return (KORE_RESULT_OK); diff --git a/src/utils.c b/src/utils.c @@ -225,6 +225,38 @@ kore_strtonum64(const char *str, int sign, int *err) return ((sign) ? (u_int64_t)ll : l); } +double +kore_strtodouble(const char *str, long double min, long double max, int *err) +{ + double d; + char *ep; + + if (min > max) { + *err = KORE_RESULT_ERROR; + return (0); + } + + errno = 0; + d = strtod(str, &ep); + if (d == 0 || errno == ERANGE || str == ep || *ep != '\0') { + *err = KORE_RESULT_ERROR; + return (0); + } + + if (d < min) { + *err = KORE_RESULT_ERROR; + return (0); + } + + if (d > max) { + *err = KORE_RESULT_ERROR; + return (0); + } + + *err = KORE_RESULT_OK; + return (d); +} + int kore_split_string(char *input, const char *delim, char **out, size_t ele) {