From 920878096a1721fd6e0c1b7008abac51803c5aa4 Mon Sep 17 00:00:00 2001 From: ꦌꦫꦶꦏ꧀ꦦꦿꦧꦮꦑꦩꦭ꧀ Date: Fri, 16 Jul 2021 10:51:24 +0800 Subject: Generalise the response handler so the common part gets to be reused. --- handler.h | 75 ++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 43 insertions(+), 32 deletions(-) (limited to 'handler.h') diff --git a/handler.h b/handler.h index 9c46975..065820c 100644 --- a/handler.h +++ b/handler.h @@ -8,8 +8,10 @@ extern json_tokener *tokener; void recurse(struct json_object *, const char *[], struct json_object **); -inline void handle_services(const char *contents, size_t num_bytes, const char *status_trail[], - const char *trail[], const char *attributes[], struct pikul_services **services) +enum type { SERVICES, ORDER }; + +inline void handle(enum type type, const char *contents, size_t num_bytes, const char *status_trail[], + const char *trail[], const char *attributes[], void *data) { #ifdef DEBUG ((char *)contents)[num_bytes] = '\0'; @@ -30,37 +32,46 @@ inline void handle_services(const char *contents, size_t num_bytes, const char * recurse(response, status_trail, &status); if (json_object_get_int(status) != 200) return; - struct json_object *array = NULL; - recurse(response, trail, &array); - size_t length = json_object_array_length(array); - *services = malloc(sizeof(struct pikul_services) + sizeof(struct pikul_service *[length])); - (*services)->length = length; - enum { CODE, NAME, ETD, COST }; - for (size_t i = 0; i < length; i++) { - (*services)->list[i] = malloc(sizeof(struct pikul_service)); - struct pikul_service *service = (*services)->list[i]; - json_object *object = json_object_array_get_idx(array, 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 *name = json_object_iter_peek_name(&iterator); - json_object *value = json_object_iter_peek_value(&iterator); - if (!strcmp(name, attributes[COST])) - service->cost = json_object_get_double(value); - else { - int len = json_object_get_string_len(value); - if (len) { - char *string = malloc(len + 1); - strcpy(string, json_object_get_string(value)); - if (!strcmp(name, attributes[CODE])) - service->code = string; - else if (!strcmp(name, attributes[NAME])) - service->name = string; - else if (!strcmp(name, attributes[ETD])) - service->etd = string; + switch (type) { + case SERVICES: + ; + struct json_object *array = NULL; + recurse(response, trail, &array); + size_t length = json_object_array_length(array); + struct pikul_services **services = (struct pikul_services **)data; + *services = malloc(sizeof(struct pikul_services) + + sizeof(struct pikul_service *[length])); + (*services)->length = length; + enum { CODE, NAME, ETD, COST }; + for (size_t i = 0; i < length; i++) { + (*services)->list[i] = malloc(sizeof(struct pikul_service)); + struct pikul_service *service = (*services)->list[i]; + json_object *object = json_object_array_get_idx(array, 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 *name = json_object_iter_peek_name(&iterator); + json_object *value = json_object_iter_peek_value(&iterator); + if (!strcmp(name, attributes[COST])) + service->cost = json_object_get_double(value); + else { + int len = json_object_get_string_len(value); + if (len) { + char *string = malloc(len + 1); + strcpy(string, json_object_get_string(value)); + if (!strcmp(name, attributes[CODE])) + service->code = string; + else if (!strcmp(name, attributes[NAME])) + service->name = string; + else if (!strcmp(name, attributes[ETD])) + service->etd = string; + } + } + json_object_iter_next(&iterator); } } - json_object_iter_next(&iterator); - } + break; + default: + break; } } -- cgit v1.3 From 6f78942176d5909349305db37b5424a1c6ceccef Mon Sep 17 00:00:00 2001 From: ꦌꦫꦶꦏ꧀ꦦꦿꦧꦮꦑꦩꦭ꧀ Date: Fri, 16 Jul 2021 11:02:02 +0800 Subject: Order functionality draft Not tested yet. Now the item object is still flattened as an array, initially to hurry the interfacing with the Perl module. But we were stuck with having to typemap char *** anyway, so we switch to SWIG because of the potential of ease. Still, we need to typemap char ***, but now that we're at SWIG, we might as well typemap a custom item struct. --- anteraja.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 1 + handler.h | 8 ++++++ pikul.c | 43 +++++++++++++++++++++++++++ pikul.h | 4 +++ 5 files changed, 150 insertions(+) (limited to 'handler.h') diff --git a/anteraja.c b/anteraja.c index 06a9b24..aad6d04 100644 --- a/anteraja.c +++ b/anteraja.c @@ -10,9 +10,45 @@ }" #define SERVICES_WEIGHT 5 +#define ORDER_PATH "order" +#define ORDER_POST \ +"{\ +\"booking_id\":\"%s-%s\",\ +\"service_code\":\"%s\",\ +\"shipper\":{\ +\"name\":\"%s\",\ +\"phone\":\"%s\",\ +\"district\":\"%s\",\ +\"address\":\"%s\"\ +},\ +\"receiver\":{\ +\"name\":\"%s\",\ +\"phone\":\"%s\",\ +\"district\":\"%s\",\ +\"address\":\"%s\"\ +},\ +\"items\":[\ +%s\ +],\ +\"declared_value\":%d\ +}" +#define ORDER_SUBTOTAL 9 + +#define ORDER_ITEM \ +"{\ +\"item_name\":\"%s\",\ +\"item_quantity\":%d,\ +\"declared_value\":%d,\ +\"weight\":%d\ +}" +#define ORDER_ITEM_QUANTITY 2 +#define ORDER_ITEM_PRICE 9 +#define ORDER_ITEM_WEIGHT 5 + extern CURL *curl; static const char *status_trail[] = { "status", NULL }; +static char *prefix = NULL; void anteraja_init(char *provisions[]) { @@ -21,6 +57,10 @@ void anteraja_init(char *provisions[]) strcpy(shipping.base, provisions[BASE_PATH]); headers((const char *[]){ "access-key-id", "secret-access-key", NULL }, &provisions[ACCESS_KEY_ID]); shipping.headers = curl_slist_append(shipping.headers, "Content-Type:application/json"); + if (provisions[PREFIX]) { + prefix = malloc(strlen(provisions[PREFIX]) + 1); + strcpy(prefix, provisions[PREFIX]); + } } void anteraja_services(const char *origin, const char *destination, double weight, char **url, char **post) @@ -49,3 +89,57 @@ size_t anteraja_services_handle(const char *contents, size_t size, size_t nmemb, }, services); return realsize; } + +void anteraja_order(const char *trx_id, const char *service, const char *sender_name, + const char *sender_phone, const char *origin, const char *sender_address, + const char *receiver_name, const char *receiver_phone, const char *destination, + const char *receiver_address, int nitems, char **items[], double subtotal, + char **url, char **post) +{ + *url = malloc(strlen(shipping.base) + strlen(ORDER_PATH) + 1); + sprintf(*url, "%s%s", shipping.base, ORDER_PATH); + enum { SKU, QUANTITY, DESCRIPTION, PRICE, WEIGHT }; + char *json = NULL; + for (int i = 0; i < nitems; i++) { + size_t length = strlen(ORDER_ITEM) + strlen(items[i][DESCRIPTION]) + ORDER_ITEM_QUANTITY + + ORDER_ITEM_PRICE + ORDER_ITEM_WEIGHT - strlen("%s") - 3 * strlen("%d") + 1; + char item[length]; + sprintf(item, ORDER_ITEM, items[i][DESCRIPTION], atoi(items[i][QUANTITY]), + atoi(items[i][PRICE]), atoi(items[i][WEIGHT]) * 1000); + if (json) + json = realloc(json, strlen(json) + length); + else + json = malloc(length); + strcat(json, item); + if (i + 1 < nitems) + json[length] = ','; + else + json[length] = '\0'; + } + *post = malloc(strlen(ORDER_POST) + strlen(prefix) + strlen(trx_id) + strlen(service) + + strlen(sender_name) + strlen(sender_phone) + strlen(origin) + + strlen(sender_address) + strlen(receiver_name) + strlen(receiver_phone) + + strlen(destination) + strlen(receiver_address) + strlen(json) + ORDER_SUBTOTAL + - 12 * strlen("%s") - strlen("%d") + 1); + sprintf(*post, ORDER_POST, prefix, trx_id, service, sender_name, sender_phone, origin, + sender_address, receiver_name, receiver_phone, destination, receiver_address, json, + (int)subtotal); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, *post); +} + +size_t anteraja_order_handle(const char *contents, size_t size, size_t nmemb, char **waybill) +{ + size_t realsize = size * nmemb; + handle(ORDER, contents, realsize, status_trail, (const char *[]){ + "content", + "waybill_no", + NULL + }, NULL, waybill); + return realsize; +} + +void anteraja_cleanup() +{ + if (prefix) + free(prefix); +} diff --git a/configure.ac b/configure.ac index c6d63c1..5dbace7 100644 --- a/configure.ac +++ b/configure.ac @@ -7,6 +7,7 @@ PKG_CHECK_MODULES([DEPS], [libcurl json-c]) AC_TYPE_SIZE_T AC_C_INLINE AC_FUNC_MALLOC +AC_FUNC_REALLOC AC_CHECK_FUNCS([memset]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([Makefile]) diff --git a/handler.h b/handler.h index 065820c..e940d91 100644 --- a/handler.h +++ b/handler.h @@ -71,6 +71,14 @@ inline void handle(enum type type, const char *contents, size_t num_bytes, const } } break; + case ORDER: + ; + struct json_object *string = NULL; + recurse(response, trail, &string); + char **waybill = (char **)data; + *waybill = malloc(json_object_get_string_len(string) + 1); + strcpy(*waybill, json_object_get_string(string)); + break; default: break; } diff --git a/pikul.c b/pikul.c index 5dd0750..d299cbe 100644 --- a/pikul.c +++ b/pikul.c @@ -4,6 +4,7 @@ CURL *curl; json_tokener *tokener; struct shipping shipping; +static char *waybill = NULL; extern inline void headers(const char *[], char *[]); extern inline void handle(enum type, const char *, size_t, const char *[], const char *[], const char *[], @@ -12,6 +13,11 @@ extern inline void handle(enum type, const char *, size_t, const char *[], const extern void anteraja_init(char *[]); extern void anteraja_services(const char *, const char *, double, char **, char **); extern size_t anteraja_services_handle(const char *, size_t, size_t, struct pikul_services **); +extern void anteraja_order(const char *, const char *, const char *, const char *, const char *, + const char *, const char *, const char *, const char *, const char *, int, + char **[], double, char **, char **); +extern size_t anteraja_order_handle(const char *, size_t size, size_t nmemb, char **); +extern void anteraja_cleanup(); void pikul_init(enum pikul_company company, char *provisions[]) { @@ -106,8 +112,45 @@ double pikul_cost(const char *origin, const char *destination, double weight, co return cost; } +char *pikul_order(const char *trx_id, const char *service, const char *sender_name, + const char *sender_phone, const char *origin, const char *sender_address, + const char *receiver_name, const char *receiver_phone, const char *destination, + const char *receiver_address, int nitems, char **items[], double subtotal) +{ + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &waybill); + char *url; + char *post = NULL; + size_t (*handler)(const char *, size_t, size_t, char **); + switch (shipping.company) { + case PIKUL_ANTERAJA: + anteraja_order(trx_id, service, sender_name, sender_phone, origin, sender_address, + receiver_name, receiver_phone, destination, receiver_address, + nitems, items, subtotal, &url, &post); + handler = anteraja_order_handle; + break; + default: + break; + } + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, handler); + curl_easy_perform(curl); + if (post) + free(post); + free(url); + return waybill; +} + void pikul_cleanup() { + switch (shipping.company) { + case PIKUL_ANTERAJA: + anteraja_cleanup(); + break; + default: + break; + } + if (waybill) + free(waybill); free(shipping.base); json_tokener_free(tokener); curl_slist_free_all(shipping.headers); diff --git a/pikul.h b/pikul.h index 4cd11f7..d88d218 100644 --- a/pikul.h +++ b/pikul.h @@ -25,6 +25,10 @@ void pikul_init(enum pikul_company company, char *provisions[]); struct pikul_services *pikul_services(const char *origin, const char *destination, double weight); void pikul_free_services(struct pikul_services *services); double pikul_cost(const char *origin, const char *destination, double weight, const char *service); +char *pikul_order(const char *trx_id, const char *service, const char *sender_name, + const char *sender_phone, const char *origin, const char *sender_address, + const char *receiver_name, const char *receiver_phone, const char *destination, + const char *receiver_address, int nitems, char **items[], double value); void pikul_cleanup(); #ifdef __cplusplus -- cgit v1.3 From 2419d61c5171479586ba606834dcbfaa138c9bb3 Mon Sep 17 00:00:00 2001 From: ꦌꦫꦶꦏ꧀ꦦꦿꦧꦮꦑꦩꦭ꧀ Date: Sat, 17 Jul 2021 20:47:59 +0800 Subject: Rename waybill to tracking_number --- anteraja.c | 4 ++-- handler.h | 6 +++--- pikul.c | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'handler.h') diff --git a/anteraja.c b/anteraja.c index 14e32a0..0e5f2e7 100644 --- a/anteraja.c +++ b/anteraja.c @@ -146,14 +146,14 @@ void anteraja_order(const char *order_number, const char *service, const char *s curl_easy_setopt(curl, CURLOPT_POSTFIELDS, *post); } -size_t anteraja_order_handle(const char *contents, size_t size, size_t nmemb, char **waybill) +size_t anteraja_order_handle(const char *contents, size_t size, size_t nmemb, char **tracking_number) { size_t realsize = size * nmemb; handle(ORDER, contents, realsize, status_trail, (const char *[]){ "content", "waybill_no", NULL - }, NULL, waybill); + }, NULL, tracking_number); return realsize; } diff --git a/handler.h b/handler.h index e940d91..a2c031b 100644 --- a/handler.h +++ b/handler.h @@ -75,9 +75,9 @@ inline void handle(enum type type, const char *contents, size_t num_bytes, const ; struct json_object *string = NULL; recurse(response, trail, &string); - char **waybill = (char **)data; - *waybill = malloc(json_object_get_string_len(string) + 1); - strcpy(*waybill, json_object_get_string(string)); + char **tracking_number = (char **)data; + *tracking_number = malloc(json_object_get_string_len(string) + 1); + strcpy(*tracking_number, json_object_get_string(string)); break; default: break; diff --git a/pikul.c b/pikul.c index cb74feb..b3e6352 100644 --- a/pikul.c +++ b/pikul.c @@ -4,7 +4,7 @@ CURL *curl; json_tokener *tokener; struct shipping shipping; -static char *waybill = NULL; +static char *tracking_number = NULL; extern inline void headers(const char *[], char *[]); extern inline void handle(enum type, const char *, size_t, const char *[], const char *[], const char *[], @@ -118,7 +118,7 @@ char *pikul_order(const char *order_number, const char *service, const char *sen const char *destination, const char *receiver_address, const char *receiver_postal, int nitems, char **items[], _Bool insurance, double subtotal) { - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &waybill); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &tracking_number); char *url; char *post = NULL; size_t (*handler)(const char *, size_t, size_t, char **); @@ -139,7 +139,7 @@ char *pikul_order(const char *order_number, const char *service, const char *sen if (post) free(post); free(url); - return waybill; + return tracking_number; } void pikul_cleanup() @@ -151,8 +151,8 @@ void pikul_cleanup() default: break; } - if (waybill) - free(waybill); + if (tracking_number) + free(tracking_number); free(shipping.base); json_tokener_free(tokener); curl_slist_free_all(shipping.headers); -- cgit v1.3