summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--admin.c4
-rw-r--r--client.c18
-rw-r--r--configure.ac4
-rw-r--r--icclient.h10
-rw-r--r--icclient/admin.h2
-rw-r--r--icclient/member.h4
-rw-r--r--icclient/typedefs.h8
-rw-r--r--login.c2
-rw-r--r--login.h4
-rw-r--r--main.c58
-rw-r--r--member.c8
-rw-r--r--ord.c2
-rw-r--r--request.c15
-rw-r--r--request.h77
14 files changed, 129 insertions, 87 deletions
diff --git a/admin.c b/admin.c
index 4e0fdf5..3ba9464 100644
--- a/admin.c
+++ b/admin.c
@@ -7,7 +7,7 @@ typedef struct icclient_admin icclient_admin;
icclient_admin *icclient_admin_login(const char *username, const char *password,
const char *successpage, const char *nextpage, const char *failpage,
- icclient_handler handler)
+ void (*handler)(icclient_fetch_t *))
{
icclient_admin *admin = malloc(sizeof(icclient_admin));
admin->name = NULL;
@@ -19,7 +19,7 @@ icclient_admin *icclient_admin_login(const char *username, const char *password,
void icclient_admin_newitem(const char *description, const char *comment, const char *price, const char *image_path)
{
- request(NULL, NULL, &(struct icclient_request_data){ 15, {
+ request(NULL, NULL, &(struct body){ 15, {
{ "mv_click", "process_filter" },
{ "mv_data_fields", "sku description prod_group category comment inactive price wholesale image thumb image_large weight nontaxable gift_cert" },
{ "mv_ui", "1" },
diff --git a/client.c b/client.c
index aa2a1cc..4d8530a 100644
--- a/client.c
+++ b/client.c
@@ -2,18 +2,12 @@
#include "request.h"
#include "icclient.h"
-#ifdef __EMSCRIPTEN__
-extern void icclient_catalog_results(emscripten_fetch_t *);
-#else
-extern size_t icclient_catalog_results(void *, size_t, size_t, void *);
-#endif
-
void icclient_init(const char *url, const char *certificate)
{
- icclient_request_init(url, certificate);
+ init(url, certificate);
}
-void icclient_results(const char *prod_group, void (*callback)(struct icclient_catalog *), icclient_handler handler)
+void icclient_results(const char *prod_group, void (*callback)(struct icclient_catalog *), void (*handler)(icclient_fetch_t *))
{
char nonspaced[strlen(prod_group) + 1];
strcpy(nonspaced, prod_group);
@@ -23,12 +17,12 @@ void icclient_results(const char *prod_group, void (*callback)(struct icclient_c
request(handler, (void *)callback, 0, "%s", nonspaced);
}
-void icclient_flypage(const char *sku, icclient_handler handler, struct icclient_product **productptr)
+void icclient_flypage(const char *sku, void (*handler)(icclient_fetch_t *), struct icclient_product **productptr)
{
request(handler, (void *)productptr, 0, "%s", sku);
}
-void icclient_page(const char *path, icclient_handler handler, void **dataptr)
+void icclient_page(const char *path, void (*handler)(icclient_fetch_t *), void **dataptr)
{
request(handler, (void *)dataptr, 0, "%s", path);
}
@@ -63,5 +57,7 @@ void icclient_free_catalog(struct icclient_catalog *catalog)
void icclient_cleanup()
{
- icclient_request_cleanup();
+#ifndef __EMSCRIPTEN__
+ cleanup();
+#endif
}
diff --git a/configure.ac b/configure.ac
index 91d0b6d..ba95804 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,8 @@
AC_INIT([icclient], [0.0], [pt@darapsa.co.id])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
+AM_PROG_AR
+LT_INIT
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile])
AC_CHECK_HEADER_STDBOOL
@@ -10,8 +12,6 @@ AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
-AM_PROG_AR
-LT_INIT
AC_CANONICAL_HOST
case $host_cpu in
*wasm* ) wasm=true;;
diff --git a/icclient.h b/icclient.h
index fb13ef7..d537263 100644
--- a/icclient.h
+++ b/icclient.h
@@ -1,5 +1,5 @@
-#ifndef ICCLIENT_CLIENT_H
-#define ICCLIENT_CLIENT_H
+#ifndef ICCLIENT_H
+#define ICCLIENT_H
#include <icclient/typedefs.h>
@@ -44,7 +44,7 @@ void icclient_init(const char *url, const char *certificate);
* \param callback A pointer to the function that needs to be called after the catalog is ready.
* \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, void (*callback)(struct icclient_catalog *), icclient_handler handler);
+void icclient_results(const char *prod_group, void (*callback)(struct icclient_catalog *), void (*handler)(icclient_fetch_t *));
/*!
* \brief For fetching data about a specific product.
@@ -52,9 +52,9 @@ void icclient_results(const char *prod_group, void (*callback)(struct icclient_c
* \param handler A pointer to a cURL write function callback.
* \param productptr A pointer to pointer to the product to store the data.
*/
-void icclient_flypage(const char *sku, icclient_handler handler, struct icclient_product **productptr);
+void icclient_flypage(const char *sku, void (*handler)(icclient_fetch_t *), struct icclient_product **productptr);
-void icclient_page(const char *path, icclient_handler handler, void **dataptr);
+void icclient_page(const char *path, void (*handler)(icclient_fetch_t *), void **dataptr);
void icclient_free_product(struct icclient_product *product);
diff --git a/icclient/admin.h b/icclient/admin.h
index 36ec0d6..cfc89da 100644
--- a/icclient/admin.h
+++ b/icclient/admin.h
@@ -15,7 +15,7 @@ extern "C" {
struct icclient_admin *icclient_admin_login(const char *username,
const char *password, const char *successpage,
const char *nextpage, const char *failpage,
- icclient_handler handler);
+ void (*handler)(icclient_fetch_t *));
void icclient_admin_newitem(const char *description, const char *comment,
const char *price, const char *image_path);
void icclient_admin_logout(struct icclient_admin *admin);
diff --git a/icclient/member.h b/icclient/member.h
index 1c0943a..feee6c3 100644
--- a/icclient/member.h
+++ b/icclient/member.h
@@ -62,10 +62,10 @@ extern "C" {
struct icclient_member *icclient_member_newaccount(const char *username,
const char *password, const char *verify, const char *successpage,
- const char *nextpage, const char *failpage, icclient_handler handler);
+ const char *nextpage, const char *failpage, void (*handler)(icclient_fetch_t *));
struct icclient_member *icclient_member_login(const char *username,
const char *password, const char *successpage,
- const char *nextpage, const char *failpage, icclient_handler handler);
+ const char *nextpage, const char *failpage, void (*handler)(icclient_fetch_t *));
void icclient_member_account(const char *fname, const char *lname,
const char *address1, const char *address2, const char *city,
const char *state, const char *zip, const char *email,
diff --git a/icclient/typedefs.h b/icclient/typedefs.h
index 1b2f176..c45e260 100644
--- a/icclient/typedefs.h
+++ b/icclient/typedefs.h
@@ -3,9 +3,13 @@
#ifdef __EMSCRIPTEN__
#include <emscripten/fetch.h>
-typedef void (*icclient_handler)(emscripten_fetch_t *);
+typedef emscripten_fetch_t icclient_fetch_t;
#else
-typedef size_t (*icclient_handler)(void *, size_t, size_t, void *);
+typedef struct {
+ void *userData;
+ char *data;
+ size_t numBytes;
+} icclient_fetch_t;
#endif
#endif
diff --git a/login.c b/login.c
index 8beb856..5e97f4f 100644
--- a/login.c
+++ b/login.c
@@ -1,4 +1,4 @@
#include "login.h"
extern inline void login(const char *, const char *, const char *, const char *,
- const char *, const char *, const char *, icclient_handler, void *);
+ const char *, const char *, const char *, void (*)(icclient_fetch_t *), void *);
diff --git a/login.h b/login.h
index c11b634..9ef34f2 100644
--- a/login.h
+++ b/login.h
@@ -4,9 +4,9 @@
#include "request.h"
inline void login(const char *username, const char *password, const char *verify, const char *click,
- const char *successpage, const char *nextpage, const char *failpage, icclient_handler handler, void *user)
+ const char *successpage, const char *nextpage, const char *failpage, void (*handler)(icclient_fetch_t *), void *user)
{
- request(handler, user, &(struct icclient_request_data){ 7, {
+ request(handler, user, &(struct body){ 7, {
{ "mv_username", username },
{ "mv_password", password },
{ "mv_verify", verify },
diff --git a/main.c b/main.c
index fb2e13b..45ec093 100644
--- a/main.c
+++ b/main.c
@@ -1,6 +1,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <stdbool.h>
+#include <json.h>
#include "icclient.h"
#include "icclient/member.h"
@@ -22,17 +24,55 @@ static void print_catalog(struct icclient_catalog *catalog)
product->prod_group
);
}
- icclient_catalog_free(catalog);
+ icclient_free_catalog(catalog);
}
-static size_t print_user(void *contents, size_t size, size_t nmemb, void *userData)
+static void handle_results(icclient_fetch_t *fetch)
{
- size_t realsize = size * nmemb;
- char data[realsize + 1];
- memcpy(data, contents, realsize);
- data[realsize] = '\0';
- printf("%s\n", data);
- return realsize;
+ json_tokener *tokener = json_tokener_new();
+ json_object *products = json_tokener_parse_ex(tokener, fetch->data, fetch->numBytes);
+ json_tokener_free(tokener);
+ size_t length = json_object_array_length(products);
+ struct icclient_catalog *catalog = malloc(sizeof(struct icclient_catalog) + sizeof(struct icclient_product *[length]));
+ 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];
+ memset(product, '\0', sizeof(struct icclient_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);
+ }
+ }
+ ((void (*)(struct icclient_catalog *))fetch->userData)(catalog);
+}
+
+static void print_user(icclient_fetch_t *fetch)
+{
+ printf("%s\n", fetch->data);
}
int main(int argc, char *argv[])
@@ -48,7 +88,7 @@ int main(int argc, char *argv[])
icclient_init(url, NULL);
free(url);
- icclient_allproducts(print_catalog, NULL);
+ icclient_allproducts(print_catalog, handle_results);
char *name_line = NULL;
printf("\nName: ");
diff --git a/member.c b/member.c
index 9f64ed7..c5b5e42 100644
--- a/member.c
+++ b/member.c
@@ -60,7 +60,7 @@ icclient_member *initialise(const char *username, const char *password)
icclient_member *icclient_member_newaccount(const char *username, const char *password,
const char *verify, const char *successpage, const char *nextpage,
- const char *failpage, icclient_handler handler)
+ const char *failpage, void (*handler)(icclient_fetch_t *))
{
icclient_member *member = initialise(username, password);
login(username, password, verify, "NewAccount", successpage, nextpage, failpage, handler, member);
@@ -68,7 +68,7 @@ icclient_member *icclient_member_newaccount(const char *username, const char *pa
}
icclient_member *icclient_member_login(const char *username, const char *password,
- const char *successpage, const char *nextpage, const char *failpage, icclient_handler handler)
+ const char *successpage, const char *nextpage, const char *failpage, void (*handler)(icclient_fetch_t *))
{
icclient_member *member = initialise(username, password);
login(username, password, NULL, "Login", successpage, nextpage, failpage, handler, member);
@@ -79,7 +79,7 @@ void icclient_member_account(const char *fname, const char *lname, const char *a
const char *address2, const char *city, const char *state,
const char *zip, const char *email, const char *phone_day)
{
- request(NULL, NULL, &(struct icclient_request_data){ 13, {
+ request(NULL, NULL, &(struct body){ 13, {
{ "mv_form_profile", "account_change" },
{ "mv_todo", "return" },
{ "mv_nextpage", "member/account" },
@@ -98,7 +98,7 @@ void icclient_member_account(const char *fname, const char *lname, const char *a
void icclient_member_changepassword(const char *password_old, const char *password, const char *verify)
{
- request(NULL, NULL, &(struct icclient_request_data){ 6, {
+ request(NULL, NULL, &(struct body){ 6, {
{ "mv_action", "return" },
{ "mv_check", "Change_password" },
{ "mv_successpage", "member/service" },
diff --git a/ord.c b/ord.c
index 42a5aea..f102a45 100644
--- a/ord.c
+++ b/ord.c
@@ -86,7 +86,7 @@ void icclient_ord_order(const char *sku, const icclient_catalog *catalog,
void icclient_ord_checkout(struct icclient_ord_order *order,
struct icclient_member *member)
{
- request(NULL, NULL, &(struct icclient_request_data){ 14, {
+ request(NULL, NULL, &(struct body){ 14, {
{ "mv_todo", "submit" },
{ "mv_action", "refresh" },
{ "mv_order_profile", order->profile },
diff --git a/request.c b/request.c
index 75c3073..835bf3a 100644
--- a/request.c
+++ b/request.c
@@ -5,8 +5,17 @@ emscripten_fetch_attr_t attr;
#else
CURL *curl;
char *server_url;
+size_t append(char *data, size_t size, size_t nmemb, icclient_fetch_t *fetch)
+{
+ size_t realsize = size * nmemb;
+ fetch->data = realloc(fetch->data, fetch->numBytes + realsize + 1);
+ memcpy(&(fetch->data[fetch->numBytes]), data, realsize);
+ fetch->numBytes += realsize;
+ fetch->data[fetch->numBytes] = '\0';
+ return realsize;
+}
#endif
-extern inline void icclient_request_init(const char *, const char *);
-extern inline void request(icclient_handler, void *, struct icclient_request_data *, char *, ...);
-extern inline void icclient_request_cleanup();
+extern inline void init(const char *, const char *);
+extern inline void request(void (*)(icclient_fetch_t *), void *, struct body *, char *, ...);
+extern inline void cleanup();
diff --git a/request.h b/request.h
index 19ed118..dd19400 100644
--- a/request.h
+++ b/request.h
@@ -13,9 +13,9 @@
#endif
#include "icclient/typedefs.h"
-struct icclient_request_data {
+struct body {
size_t num_pairs;
- struct icclient_request_pair {
+ struct pair {
const char *key;
const char *value;
} pairs[16];
@@ -26,9 +26,10 @@ extern emscripten_fetch_attr_t attr;
#else
extern CURL *curl;
extern char *server_url;
+size_t append(char *, size_t, size_t, icclient_fetch_t *);
#endif
-inline void icclient_request_init(const char *url, const char *certificate)
+inline void init(const char *url, const char *certificate)
{
#ifdef __EMSCRIPTEN__
emscripten_fetch_attr_init(&attr);
@@ -36,25 +37,23 @@ inline void icclient_request_init(const char *url, const char *certificate)
#else
curl_global_init(CURL_GLOBAL_SSL);
curl = curl_easy_init();
- if (curl) {
- curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
- curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "");
- if (certificate)
- curl_easy_setopt(curl, CURLOPT_CAINFO, certificate);
+ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
+ curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "");
+ if (certificate)
+ curl_easy_setopt(curl, CURLOPT_CAINFO, certificate);
#ifdef DEBUG
- curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
#endif
- size_t length = strlen(url);
- size_t append = !(url[length - 1] == '/');
- server_url = malloc(length + append + 1);
- strcpy(server_url, url);
- if (append)
- strcat(server_url, "/");
- }
+ size_t length = strlen(url);
+ size_t append = url[length - 1] != '/';
+ server_url = malloc(length + append + 1);
+ strcpy(server_url, url);
+ if (append)
+ strcat(server_url, "/");
#endif
}
-inline void request(icclient_handler writefunction, void *writedata, struct icclient_request_data *body, char *fmt, ...)
+inline void request(void (*handler)(icclient_fetch_t *), void *callback, struct body *body, char *fmt, ...)
{
va_list ap;
char *p, *sval;
@@ -89,7 +88,7 @@ inline void request(icclient_handler writefunction, void *writedata, struct iccl
char url[length + 1];
#ifdef __EMSCRIPTEN__
- memset(url, 0, length + 1);
+ memset(url, '\0', length + 1);
#else
strcpy(url, server_url);
#endif
@@ -114,22 +113,19 @@ inline void request(icclient_handler writefunction, void *writedata, struct iccl
va_end(ap);
#ifdef __EMSCRIPTEN__
- attr.onsuccess = writefunction;
- if (writedata)
- attr.userData = writedata;
+ attr.onsuccess = handler;
+ attr.userData = callback;
strcpy(attr.requestMethod, "GET");
emscripten_fetch(&attr, url);
#else
curl_easy_setopt(curl, CURLOPT_URL, url);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunction);
- if (writedata)
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, writedata);
- else
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, stdout);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, append);
+ icclient_fetch_t fetch = { .userData = callback, .numBytes = 0 };
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fetch);
struct curl_httppost *post, *last = NULL;
if (body) {
for (size_t i = 0; i < body->num_pairs; i++) {
- struct icclient_request_pair pair = body->pairs[i];
+ struct pair pair = body->pairs[i];
if (!pair.value)
continue;
curl_formadd(&post, &last,
@@ -141,34 +137,31 @@ inline void request(icclient_handler writefunction, void *writedata, struct iccl
curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
} else
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
-#ifdef DEBUG
- CURLcode res =
-#endif
- curl_easy_perform(curl);
+ CURLcode res = curl_easy_perform(curl);
if (post)
curl_formfree(post);
+ if (res == CURLE_OK)
+ handler(&fetch);
#ifdef DEBUG
- if (res != CURLE_OK) {
+ else {
const char *error = curl_easy_strerror(res);
#ifdef __ANDROID__
- __android_log_print(ANDROID_LOG_ERROR, "libicclient.so", "%s: %s", __func__, error);
+ __android_log_print(ANDROID_LOG_ERROR, "libicclient.so", "%s", error);
#else
- fprintf(stderr, "%s: %s\n", __func__, error);
-#endif
+ fprintf(stderr, "%s\n", error);
#endif
}
#endif
+#endif
}
-inline void icclient_request_cleanup()
-{
#ifndef __EMSCRIPTEN__
- if (curl) {
- free(server_url);
- curl_easy_cleanup(curl);
- }
+inline void cleanup()
+{
+ free(server_url);
+ curl_easy_cleanup(curl);
curl_global_cleanup();
-#endif
}
+#endif
#endif