From 06bea8ae54dd3cd714b231b3d8a8deef77136613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=A6=8C=EA=A6=AB=EA=A6=B6=EA=A6=8F=EA=A7=80=EA=A6=A6?= =?UTF-8?q?=EA=A6=BF=EA=A6=A7=EA=A6=AE=EA=A6=91=EA=A6=A9=EA=A6=AD=EA=A7=80?= Date: Thu, 10 Jun 2021 13:01:01 +0800 Subject: The client now takes an "on success" callback argument --- Makefile.am | 9 +++-- catalog.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ client.c | 14 ++++---- configure.ac | 2 +- icclient/catalog.h | 3 +- icclient/client.h | 19 +++++------ main.c | 26 +++++++++++++-- 7 files changed, 147 insertions(+), 24 deletions(-) diff --git a/Makefile.am b/Makefile.am index 01f7b92..680bc0e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -13,11 +13,11 @@ libicclient_la_SOURCES += \ member.c \ admin.c endif -libicclient_la_CFLAGS = -I${prefix}/include +libicclient_la_CPPFLAGS = -I${prefix}/include $(DEPS_CFLAGS) if WASM libicclient_la_LDFLAGS = -static else -libicclient_la_LDFLAGS = $(CURL_LIBS) +libicclient_la_LDFLAGS = $(DEPS_LIBS) endif if IOS libicclient_la_LDFLAGS += -static @@ -33,3 +33,8 @@ pkginclude_HEADERS += \ icclient/member.h \ icclient/admin.h endif + +bin_PROGRAMS = testicclient +testicclient_SOURCES = main.c client.c catalog.c product.c request.c +testicclient_CPPFLAGS = -I${prefix}/include $(DEPS_CFLAGS) +testicclient_LDFLAGS = $(DEPS_LIBS) diff --git a/catalog.c b/catalog.c index 27e2385..b7f7665 100644 --- a/catalog.c +++ b/catalog.c @@ -1,11 +1,109 @@ #include +#include +#include #include "icclient/product.h" #include "icclient/catalog.h" +static json_tokener *tokener = NULL; + +void icclient_catalog_init() +{ + tokener = json_tokener_new(); +} + +size_t icclient_catalog_results(void *contents, size_t size, size_t nmemb, void *userData) +{ + size_t realsize = +#ifdef __EMSCRIPTEN__ + fetch->numBytes +#else + size * nmemb +#endif + ; + char data[realsize]; + memcpy(data, contents, realsize - 1); + data[realsize - 1] = '\0'; + json_object *products = json_tokener_parse_ex(tokener, +#ifdef __EMSCRIPTEN__ + fetch-> +#endif + data, realsize); + enum json_tokener_error error = json_tokener_get_error(tokener); + if (!products) { + if (error == json_tokener_continue) + return +#ifndef __EMSCRIPTEN__ + realsize +#endif + ; + else { + json_tokener_reset(tokener); + return +#ifndef __EMSCRIPTEN__ + realsize +#endif + ; + } + } else if (!json_object_is_type(products, json_type_array) || error != json_tokener_success) + return +#ifndef __EMSCRIPTEN__ + realsize +#endif + ; + size_t length = json_object_array_length(products); + struct icclient_catalog **catalogptr = (struct icclient_catalog **) +#ifdef __EMSCRIPTEN__ + fetch-> +#endif + userData; + *catalogptr = malloc(sizeof(struct icclient_catalog) + sizeof(struct icclient_product *[length])); + struct icclient_catalog *catalog = *catalogptr; + catalog->length = length; + for (size_t i = 0; i < length; i++) { + catalog->products[i] = malloc(sizeof(struct icclient_product)); + struct icclient_product *product = catalog->products[i]; + icclient_product_init(product); + json_object *object = json_object_array_get_idx(products, i); + struct json_object_iterator iterator = json_object_iter_begin(object); + struct json_object_iterator iterator_end = json_object_iter_end(object); + while (!json_object_iter_equal(&iterator, &iterator_end)) { + const char *key = json_object_iter_peek_name(&iterator); + json_object *val = json_object_iter_peek_value(&iterator); + if (!strcmp(key, "price")) + product->price = json_object_get_double(val); + else { + int len = json_object_get_string_len(val); + if (len) { + char *value = malloc(len + 1); + strcpy(value, json_object_get_string(val)); + if (!strcmp(key, "sku")) + product->sku = value; + else if (!strcmp(key, "thumb")) + product->thumb = value; + else if (!strcmp(key, "image")) + product->image = value; + else if (!strcmp(key, "description")) + product->description = value; + else if (!strcmp(key, "prod_group")) + product->prod_group = value; + } + } + json_object_iter_next(&iterator); + } + } +#ifdef __EMSCRIPTEN__ + emscripten_fetch_close(fetch); +#else + return realsize; +#endif +} + void icclient_catalog_free(struct icclient_catalog *catalog) { for (size_t i = 0; i < catalog->length; i++) icclient_product_free(catalog->products[i]); free(catalog); catalog = NULL; + json_tokener_free(tokener); + } diff --git a/client.c b/client.c index 0dad4c9..8813db9 100644 --- a/client.c +++ b/client.c @@ -37,23 +37,23 @@ bool icclient_init(const char *url, const char *certificate) if (append) strcat(server_url, "/"); } + icclient_catalog_init(); return (bool)curl; #endif } -void icclient_results(const char *prod_group, icclient_handler handler, struct icclient_catalog **catalogptr) +extern size_t icclient_catalog_results(void *, size_t, size_t, void *); + +void icclient_results(const char *prod_group, + void (*callback)(struct icclient_catalog *), struct icclient_catalog **catalog, icclient_handler handler) { char nonspaced[strlen(prod_group) + 1]; strcpy(nonspaced, prod_group); char *space = NULL; while ((space = strchr(nonspaced, ' '))) *space = '-'; - request(handler, (void *)catalogptr, 0, "%s", nonspaced); -} - -void icclient_allproducts(icclient_handler handler, struct icclient_catalog **catalogptr) -{ - request(handler, (void *)catalogptr, 0, "%s", "All-Products"); + request(handler ? handler : icclient_catalog_results, (void *)catalog, 0, "%s", nonspaced); + callback(*catalog); } void icclient_flypage(const char *sku, icclient_handler handler, struct icclient_product **productptr) diff --git a/configure.ac b/configure.ac index 1e94187..31ff210 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AC_PROG_CC AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([Makefile]) -PKG_CHECK_EXISTS([CURL], [libcurl]) +PKG_CHECK_MODULES([DEPS], [libcurl json-c]) AC_CHECK_HEADER_STDBOOL AC_C_INLINE AC_CHECK_FUNCS([memset]) diff --git a/icclient/catalog.h b/icclient/catalog.h index ee65c1e..677d691 100644 --- a/icclient/catalog.h +++ b/icclient/catalog.h @@ -10,10 +10,11 @@ struct icclient_catalog { extern "C" { #endif + void icclient_catalog_init(); void icclient_catalog_free(struct icclient_catalog *catalog); #ifdef __cplusplus } #endif -#endif // ICCLIENT_CATALOG_H +#endif diff --git a/icclient/client.h b/icclient/client.h index 00f9445..5c0541b 100644 --- a/icclient/client.h +++ b/icclient/client.h @@ -19,17 +19,12 @@ extern "C" { /*! * \brief For fetching data about products that belong a specific group. * \param prod_group The name of the product group. - * \param handler A pointer to a cURL write function callback. - * \param catalogptr A pointer to pointer to the catalog to store the data. + * \param callback A pointer to the function that needs to be called after the catalog is ready. + * \param catalog A pointer to pointer to the catalog to store the data. + * \param handler A pointer to the function when a custom handler is needed to arrange the data into the catalog. */ - void icclient_results(const char *prod_group, icclient_handler handler, struct icclient_catalog **catalogptr); - - /*! - * \brief For fetching data about all active products. - * \param handler A pointer to a cURL write function callback. - * \param catalogptr A pointer to pointer to the catalog to store the data. - */ - void icclient_allproducts(icclient_handler handler, struct icclient_catalog **catalogptr); + void icclient_results(const char *prod_group, void (*callback)(struct icclient_catalog *), + struct icclient_catalog **catalog, icclient_handler handler); /*! * \brief For fetching data about a specific product. @@ -46,4 +41,6 @@ extern "C" { } #endif -#endif // ICCLIENT_CLIENT_H +#define icclient_allproducts(callback, catalog, handler) icclient_results("All-Products", callback, catalog, handler) + +#endif diff --git a/main.c b/main.c index 68f5867..3c0aa3f 100644 --- a/main.c +++ b/main.c @@ -2,37 +2,59 @@ #include #include #include +#include +#include +#include #include +static void callback(struct icclient_catalog *catalog) +{ + for (size_t i = 0; i < catalog->length; i++) { + struct icclient_product *product = catalog->products[i]; + printf("SKU: %s\n", product->sku); + } +} + int main(void) { char *url_line = NULL, *name_line = NULL, *pass_line = NULL; printf("URL: "); ssize_t url_nread = getline(&url_line, &(size_t){0}, stdin); + /* printf("Name: "); ssize_t name_nread = getline(&name_line, &(size_t){0}, stdin); printf("Pass: "); ssize_t pass_nread = getline(&pass_line, &(size_t){0}, stdin); + */ - char *url = malloc(--url_nread + 1), *name = malloc(--name_nread + 1) + char *url = malloc(--url_nread + 1); + /* + , *name = malloc(--name_nread + 1) , *pass = malloc(--pass_nread + 1); + */ strncpy(url, url_line, url_nread); free(url_line); + /* strncpy(name, name_line, name_nread); free(name_line); strncpy(pass, pass_line, pass_nread); free(pass_line); + */ icclient_init(url, NULL); free(url); + /* icclient_login(NULL, NULL, name, pass, NULL, NULL, NULL); free(name); free(pass); icclient_logout(); + */ - icclient_allproducts(NULL, NULL); + struct icclient_catalog *catalog; + icclient_allproducts(callback, &catalog, NULL); + icclient_catalog_free(catalog); icclient_cleanup(); } -- cgit v1.2.3