summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorꦌꦫꦶꦏ꧀ꦦꦿꦧꦮꦑꦩꦭ꧀ <erik@darapsa.co.id>2021-07-19 17:38:51 +0800
committerꦌꦫꦶꦏ꧀ꦦꦿꦧꦮꦑꦩꦭ꧀ <erik@darapsa.co.id>2021-07-19 17:38:51 +0800
commit3533297ec2cf539672a362ff931d0b15c9cb38ff (patch)
tree15d2ab09c8c4b2a6863ec05f29146875ed0b39e7
parent531aaf6e9d01a4ae3257579996681bbe8246630f (diff)
parent74028cd953f94cfd2d0a1f635ed07e25d94c6802 (diff)
Merge branch 'master' into sicepat
-rw-r--r--anteraja.c86
-rw-r--r--common.h102
-rw-r--r--pikul.c185
-rw-r--r--private.h17
-rw-r--r--sicepat.c61
5 files changed, 217 insertions, 234 deletions
diff --git a/anteraja.c b/anteraja.c
index 057b22e..87438dd 100644
--- a/anteraja.c
+++ b/anteraja.c
@@ -1,4 +1,6 @@
-#include "common.h"
+#include <stdlib.h>
+#include <string.h>
+#include "private.h"
#define SERVICES_PATH "serviceRates"
#define SERVICES_POST \
@@ -50,56 +52,55 @@
#define ORDER_ITEM_PRICE 9
#define ORDER_ITEM_WEIGHT 5
-static const char *status_trail[] = { "status", NULL };
static char *prefix = NULL;
-void anteraja_init(char *provisions[])
+const char **anteraja_init(char *provisions[])
{
- enum { BASE_PATH, ACCESS_KEY_ID, SECRET_ACCESS_KEY, PREFIX };
+ enum { ACCESS_KEY_ID, SECRET_ACCESS_KEY, BASE_PATH, PREFIX };
shipping.base = malloc(strlen(provisions[BASE_PATH]) + 1);
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]);
}
+ shipping.headers = curl_slist_append(shipping.headers, "Content-Type:application/json");
+ static const char *status_trail[] = { "status", NULL };
+ shipping.status_trail = status_trail;
+ static const char *fields[] = { "access-key-id", "secret-access-key", NULL };
+ return fields;
}
-void anteraja_services(const char *origin, const char *destination, double weight, char **url, char **post)
-{
- *url = malloc(strlen(shipping.base) + strlen(SERVICES_PATH) + 1);
- sprintf(*url, "%s%s", shipping.base, SERVICES_PATH);
- *post = malloc(strlen(SERVICES_POST) + strlen(origin) + strlen(destination) + SERVICES_WEIGHT
- - 2 * strlen("%s") - strlen("%d") + 1);
- sprintf(*post, SERVICES_POST, origin, destination, weight < 1.0 ? 1000 : (int)weight * 1000);
-}
-
-size_t anteraja_services_handle(const char *contents, size_t size, size_t nmemb,
- struct pikul_services **services)
+const char **anteraja_services(const char *origin, const char *destination, double weight)
{
- size_t realsize = size * nmemb;
- handle(SERVICES, contents, realsize, status_trail, (const char *[]){
- "content",
- "services",
- NULL
- }, (const char *[]){
- "product_code",
- "product_name",
- "etd",
- "rates"
- }, services);
- return realsize;
+ shipping.url = malloc(strlen(shipping.base) + strlen(SERVICES_PATH) + 1);
+ sprintf(shipping.url, "%s%s", shipping.base, SERVICES_PATH);
+ shipping.post = malloc(strlen(SERVICES_POST) + strlen(origin) + strlen(destination)
+ + SERVICES_WEIGHT - 2 * strlen("%s") - strlen("%d") + 1);
+ sprintf(shipping.post, SERVICES_POST, origin, destination,
+ weight < 1.0 ? 1000 : (int)weight * 1000);
+ static const char *trail[] = {
+ "content",
+ "services",
+ NULL
+ };
+ shipping.trail = trail;
+ static const char *attributes[] = {
+ "product_code",
+ "product_name",
+ "etd",
+ "rates"
+ };
+ return attributes;
}
void anteraja_order(const char *order_number, const char *service, const char *sender_name,
const char *sender_phone, const char *origin, const char *sender_address,
const char *sender_postal, const char *receiver_name, const char *receiver_phone,
const char *destination, const char *receiver_address, const char *receiver_postal,
- int nitems, char **items[], double subtotal, char **url, char **post)
+ int nitems, char **items[], double subtotal)
{
- *url = malloc(strlen(shipping.base) + strlen(ORDER_PATH) + 1);
- sprintf(*url, "%s%s", shipping.base, ORDER_PATH);
+ shipping.url = malloc(strlen(shipping.base) + strlen(ORDER_PATH) + 1);
+ sprintf(shipping.url, "%s%s", shipping.base, ORDER_PATH);
enum { SKU, QUANTITY, DESCRIPTION, PRICE, WEIGHT };
char *json = NULL;
double total_weight = .0;
@@ -131,27 +132,22 @@ void anteraja_order(const char *order_number, const char *service, const char *s
else
json[strlen(json)] = '\0';
}
- *post = malloc(strlen(ORDER_POST) + strlen(prefix) + strlen(order_number) + strlen(service)
+ shipping.post = malloc(strlen(ORDER_POST) + strlen(prefix) + strlen(order_number) + strlen(service)
+ ORDER_WEIGHT + strlen(sender_name) + strlen(sender_phone) + strlen(origin)
+ strlen(sender_address) + strlen(sender_postal) + strlen(receiver_name)
+ strlen(receiver_phone) + strlen(destination) + strlen(receiver_address)
+ strlen(receiver_postal) + strlen(json) + ORDER_INSURANCE + ORDER_SUBTOTAL
- 15 * strlen("%s") - 2 * strlen("%d") + 1);
- sprintf(*post, ORDER_POST, prefix, order_number, service, (int)total_weight, sender_name,
+ sprintf(shipping.post, ORDER_POST, prefix, order_number, service, (int)total_weight, sender_name,
sender_phone, origin, sender_address, sender_postal, receiver_name, receiver_phone,
destination, receiver_address, receiver_postal, json,
total_weight < 1000.0 ? "true" : "false", subtotal < 1000.0 ? 1000 : (int)subtotal);
-}
-
-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, tracking_number);
- return realsize;
+ static const char *trail[] = {
+ "content",
+ "waybill_no",
+ NULL
+ };
+ shipping.trail = trail;
}
void anteraja_cleanup()
diff --git a/common.h b/common.h
deleted file mode 100644
index bef5e73..0000000
--- a/common.h
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifdef DEBUG
-#include <stdio.h>
-#endif
-#include <string.h>
-#include <curl/curl.h>
-#include <json.h>
-#include "pikul.h"
-
-extern struct shipping {
- enum pikul_company company;
- char *base;
- struct curl_slist *headers;
-} shipping;
-extern json_tokener *tokener;
-
-void recurse(struct json_object *, const char *[], struct json_object **);
-
-enum type { SERVICES, ORDER };
-
-inline void headers(const char *fields[], char *provisions[])
-{
- shipping.headers = NULL;
- while (*fields) {
- char header[strlen(*fields) + strlen(*provisions) + 2];
- sprintf(header, "%s:%s", *fields++, *provisions++);
- shipping.headers = curl_slist_append(shipping.headers, header);
- }
-}
-
-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';
- fprintf(stderr, "%s\n", contents);
-#endif
- json_object *response = json_tokener_parse_ex(tokener, contents, num_bytes);
- enum json_tokener_error error = json_tokener_get_error(tokener);
- if (!response) {
- if (error == json_tokener_continue)
- return;
- else {
- json_tokener_reset(tokener);
- return;
- }
- } else if (!json_object_is_type(response, json_type_object) || error != json_tokener_success)
- return;
- struct json_object *status = NULL;
- recurse(response, status_trail, &status);
- if (json_object_get_int(status) != 200)
- return;
- 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);
- }
- }
- break;
- case ORDER:
- ;
- struct json_object *string = NULL;
- recurse(response, trail, &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 7d0e739..dfb6af8 100644
--- a/pikul.c
+++ b/pikul.c
@@ -1,87 +1,165 @@
-#include "common.h"
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+#include <string.h>
+#include <json.h>
+#include "private.h"
CURL *curl;
json_tokener *tokener;
struct shipping shipping;
-void headers(const char *[], char *[]);
-void handle(enum type, const char *, size_t, const char *[], const char *[], const char *[], void *);
-
-void anteraja_init(char *[]);
-void anteraja_services(const char *, const char *, double, char **, char **);
-size_t anteraja_services_handle(const char *, size_t, size_t, struct pikul_services **);
+const char **anteraja_init(char *[]);
+const char **anteraja_services(const char *, const char *, double);
void anteraja_order(const char *, const char *, 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 **);
-size_t anteraja_order_handle(const char *, size_t size, size_t nmemb, char **);
+ char **[], double);
void anteraja_cleanup();
-void sicepat_init(char *[]);
-void sicepat_services(const char *, const char *, double, char **);
-size_t sicepat_services_handle(const char *, size_t, size_t, struct pikul_services **);
+const char **sicepat_init(char *[]);
+const char **sicepat_services(const char *, const char *, double);
+
+static void recurse(struct json_object *outer, const char *trail[], struct json_object **last)
+{
+ struct json_object *inner = NULL;
+ json_object_object_get_ex(outer, *trail, &inner);
+ if (*++trail)
+ recurse(inner, trail, last);
+ else
+ *last = inner;
+}
+
+static size_t handle(char *contents, size_t size, size_t nmemb, void *data)
+{
+ size_t realsize = size * nmemb;
+#ifdef DEBUG
+ contents[realsize] = '\0';
+ fprintf(stderr, "%s\n", contents);
+#endif
+ json_object *response = json_tokener_parse_ex(tokener, contents, realsize);
+ enum json_tokener_error error = json_tokener_get_error(tokener);
+ if (!response) {
+ if (error == json_tokener_continue)
+ return realsize;
+ else {
+ json_tokener_reset(tokener);
+ return realsize;
+ }
+ } else if (!json_object_is_type(response, json_type_object) || error != json_tokener_success)
+ return realsize;
+ struct json_object *status = NULL;
+ recurse(response, shipping.status_trail, &status);
+ if (json_object_get_int(status) != 200)
+ return realsize;
+ switch (shipping.mode) {
+ case SERVICES:
+ ;
+ struct json_object *array = NULL;
+ recurse(response, shipping.trail, &array);
+ size_t length = json_object_array_length(array);
+ shipping.data = malloc(sizeof(struct pikul_services)
+ + sizeof(struct pikul_service *[length]));
+ struct pikul_services *services = (struct pikul_services *)shipping.data;
+ services->length = length;
+ const char **attributes = (const char **)data;
+ 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);
+ }
+ }
+ break;
+ case ORDER:
+ ;
+ struct json_object *string = NULL;
+ recurse(response, shipping.trail, &string);
+ shipping.data = malloc(json_object_get_string_len(string) + 1);
+ strcpy(shipping.data, json_object_get_string(string));
+ break;
+ default:
+ break;
+ }
+ return realsize;
+}
void pikul_init(enum pikul_company company, char *provisions[])
{
curl_global_init(CURL_GLOBAL_SSL);
curl = curl_easy_init();
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, handle);
#ifdef DEBUG
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
#endif
shipping.company = company;
+ shipping.headers = NULL;
+ const char **fields;
switch (company) {
case PIKUL_ANTERAJA:
- anteraja_init(provisions);
+ fields = anteraja_init(provisions);
break;
case PIKUL_SICEPAT:
- sicepat_init(provisions);
+ fields = sicepat_init(provisions);
break;
default:
break;
}
+ while (*fields) {
+ char header[strlen(*fields) + strlen(":") + strlen(*provisions) + 1];
+ sprintf(header, "%s:%s", *fields++, *provisions++);
+ shipping.headers = curl_slist_append(shipping.headers, header);
+ }
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, shipping.headers);
tokener = json_tokener_new();
}
-void recurse(struct json_object *outer, const char *trail[], struct json_object **last)
-{
- struct json_object *inner = NULL;
- json_object_object_get_ex(outer, *trail, &inner);
- if (*++trail)
- recurse(inner, trail, last);
- else
- *last = inner;
-}
-
struct pikul_services *pikul_services(const char *origin, const char *destination, double weight)
{
- struct pikul_services *services = NULL;
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, &services);
- char *url;
- char *post = NULL;
- size_t (*handler)(const char *, size_t, size_t, struct pikul_services **);
+ shipping.post = NULL;
+ const char **attributes;
switch (shipping.company) {
case PIKUL_ANTERAJA:
- anteraja_services(origin, destination, weight, &url, &post);
- handler = anteraja_services_handle;
+ attributes = anteraja_services(origin, destination, weight);
break;
case PIKUL_SICEPAT:
- sicepat_services(origin, destination, weight, &url);
- handler = sicepat_services_handle;
+ attributes = sicepat_services(origin, destination, weight);
break;
default:
break;
}
- curl_easy_setopt(curl, CURLOPT_URL, url);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, handler);
- if (post)
- curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post);
+ curl_easy_setopt(curl, CURLOPT_URL, shipping.url);
+ if (shipping.post)
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, shipping.post);
else
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
+ shipping.mode = SERVICES;
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, attributes);
curl_easy_perform(curl);
- if (post)
- free(post);
- free(url);
- return services;
+ if (shipping.post)
+ free(shipping.post);
+ free(shipping.url);
+ return (struct pikul_services *)shipping.data;
}
static inline void free_service(struct pikul_service *service)
@@ -130,33 +208,28 @@ 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[], double subtotal)
{
- char *tracking_number = NULL;
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, &tracking_number);
- char *url;
- char *post = NULL;
- size_t (*handler)(const char *, size_t, size_t, char **);
+ shipping.post = NULL;
switch (shipping.company) {
case PIKUL_ANTERAJA:
anteraja_order(order_number, service, sender_name, sender_phone, origin,
sender_address, sender_postal, receiver_name, receiver_phone,
destination, receiver_address, receiver_postal, nitems, items,
- subtotal, &url, &post);
- handler = anteraja_order_handle;
+ subtotal);
break;
default:
break;
}
- curl_easy_setopt(curl, CURLOPT_URL, url);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, handler);
- if (post)
- curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post);
+ curl_easy_setopt(curl, CURLOPT_URL, shipping.url);
+ if (shipping.post)
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, shipping.post);
else
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
+ shipping.mode = ORDER;
curl_easy_perform(curl);
- if (post)
- free(post);
- free(url);
- return tracking_number;
+ if (shipping.post)
+ free(shipping.post);
+ free(shipping.url);
+ return (char *)shipping.data;
}
void pikul_cleanup()
diff --git a/private.h b/private.h
new file mode 100644
index 0000000..6df3e91
--- /dev/null
+++ b/private.h
@@ -0,0 +1,17 @@
+#include <curl/curl.h>
+#include "pikul.h"
+
+extern struct shipping {
+ enum pikul_company company;
+ char *base;
+ struct curl_slist *headers;
+ const char **status_trail;
+ char *url;
+ char *post;
+ enum {
+ SERVICES,
+ ORDER
+ } mode;
+ const char **trail;
+ void *data;
+} shipping;
diff --git a/sicepat.c b/sicepat.c
index 1fedbfd..9ea4af5 100644
--- a/sicepat.c
+++ b/sicepat.c
@@ -1,42 +1,41 @@
-#include "common.h"
+#include <stdlib.h>
+#include <string.h>
+#include "private.h"
#define BASE "http://api.sicepat.com/customer/"
-static const char *status_trail[] = {
- "sicepat",
- "status",
- "code",
- NULL
-};
-
-void sicepat_init(char *provisions[])
+const char **sicepat_init(char *provisions[])
{
shipping.base = malloc(strlen(BASE) + 1);
strcpy(shipping.base, BASE);
- headers((const char *[]){ "api-key", NULL }, provisions);
+ static const char *status_trail[] = {
+ "sicepat",
+ "status",
+ "code",
+ NULL
+ };
+ shipping.status_trail = status_trail;
+ static const char *fields[] = { "api-key", NULL };
+ return fields;
}
-void sicepat_services(const char *origin, const char *destination, double weight, char **url)
+const char **sicepat_services(const char *origin, const char *destination, double weight)
{
- *url = malloc(strlen(shipping.base) + strlen("tariff?origin=") + strlen(origin)
+ shipping.url = malloc(strlen(shipping.base) + strlen("tariff?origin=") + strlen(origin)
+ strlen("&destination=") + strlen(destination) + strlen("&weight=") + 9);
- sprintf(*url, "%stariff?origin=%s&destination=%s&weight=%f", shipping.base, origin, destination,
- weight);
-}
-
-size_t sicepat_services_handle(const char *contents, size_t size, size_t nmemb,
- struct pikul_services **services)
-{
- size_t realsize = size * nmemb;
- handle(SERVICES, contents, realsize, status_trail, (const char *[]){
- "sicepat",
- "results",
- NULL
- }, (const char *[]){
- "service",
- "description",
- "etd",
- "tariff"
- }, services);
- return realsize;
+ sprintf(shipping.url, "%stariff?origin=%s&destination=%s&weight=%f", shipping.base, origin,
+ destination, weight);
+ static const char *trail[] = {
+ "sicepat",
+ "results",
+ NULL
+ };
+ shipping.trail = trail;
+ static const char *attributes[] = {
+ "service",
+ "description",
+ "etd",
+ "tariff"
+ };
+ return attributes;
}