initial commit
This commit is contained in:
commit
5c327958e2
179
main.c
Normal file
179
main.c
Normal file
@ -0,0 +1,179 @@
|
||||
#include <curl/curl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <cjson/cJSON.h>
|
||||
|
||||
#define BASE_URL_SIZE 38
|
||||
|
||||
/**
|
||||
* struct string_t
|
||||
* char* buf - The buffer containing the string data
|
||||
* size_t len - The length of the buffer
|
||||
*/
|
||||
typedef struct string_t {
|
||||
char* buf;
|
||||
size_t len;
|
||||
} string;
|
||||
|
||||
/**
|
||||
* void init_string
|
||||
* string* s - The string struct
|
||||
*
|
||||
* Initializes the string struct */
|
||||
void init_string (string* s)
|
||||
{
|
||||
s->len = 0;
|
||||
s->buf = malloc(s->len + 1);
|
||||
|
||||
if (NULL == s->buf) {
|
||||
fprintf(stderr, "malloc() failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
s->buf[0] = '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* size_t writefunc
|
||||
*
|
||||
* The arguments come from CURLOPT_WRITEFUNCTION
|
||||
*
|
||||
* Writes the cURL get into the string struct
|
||||
*/
|
||||
size_t writefunc(void* ptr, size_t size, size_t nmemb, string* s)
|
||||
{
|
||||
size_t new_len = s->len + (size * nmemb);
|
||||
s->buf = realloc(s->buf, new_len + 1);
|
||||
if (NULL == s->buf) {
|
||||
fprintf(stderr, "realloc() failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
memcpy(s->buf + s->len, ptr, size * nmemb);
|
||||
s->buf[new_len] = '\0';
|
||||
s->len = new_len;
|
||||
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
/**
|
||||
* CURLcode perform_book_get
|
||||
* char isbn_buf[14] - The ISBN
|
||||
* string* s - The string struct to place the GET output in
|
||||
*
|
||||
* Perforrms a GET request with the ISBN
|
||||
*/
|
||||
CURLcode perform_book_get(char isbn_buf[14], string* s)
|
||||
{
|
||||
CURL* handler;
|
||||
char *base_url;
|
||||
size_t finalurl_size = BASE_URL_SIZE + 15;
|
||||
char finalurl[finalurl_size];
|
||||
CURLcode result;
|
||||
|
||||
handler = curl_easy_init();
|
||||
if (!handler) {
|
||||
fprintf(stderr, "cURL failed to initialize!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
base_url = "https://openlibrary.org/search.json?q=";
|
||||
/**
|
||||
* Setup the URL for the request
|
||||
*/
|
||||
snprintf(finalurl, finalurl_size, "%s%s", base_url, isbn_buf);
|
||||
|
||||
curl_easy_setopt(handler, CURLOPT_URL, finalurl);
|
||||
curl_easy_setopt(handler, CURLOPT_HTTPGET, 1L);
|
||||
curl_easy_setopt(handler, CURLOPT_WRITEFUNCTION, writefunc);
|
||||
curl_easy_setopt(handler, CURLOPT_WRITEDATA, s);
|
||||
|
||||
result = curl_easy_perform(handler);
|
||||
|
||||
// Always clean up
|
||||
curl_easy_cleanup(handler);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void parse_json(string* s)
|
||||
{
|
||||
cJSON* json = cJSON_Parse(s->buf);
|
||||
if (NULL == json) {
|
||||
const char* error_ptr = cJSON_GetErrorPtr();
|
||||
if (NULL != error_ptr)
|
||||
fprintf(stderr, "JSON error: %s\n", error_ptr);
|
||||
cJSON_Delete(json);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
cJSON* docs = cJSON_GetObjectItemCaseSensitive(json, "docs");
|
||||
cJSON* child = docs->child; // this is the JSON object that stores all of the books information
|
||||
|
||||
printf("Title: %s\n", cJSON_GetObjectItemCaseSensitive(child, "title")->valuestring);
|
||||
|
||||
cJSON* authors = cJSON_GetObjectItemCaseSensitive(child, "author_name");
|
||||
printf("Author(s): ");
|
||||
if (cJSON_IsArray(authors)) {
|
||||
cJSON* authorarr = authors->child;
|
||||
while (NULL != authorarr->next) {
|
||||
printf("%s, ", authorarr->valuestring);
|
||||
authorarr = authorarr->next;
|
||||
}
|
||||
printf("%s\n", authorarr->valuestring);
|
||||
} else {
|
||||
printf("Author(s): %s\n", authors->valuestring);
|
||||
}
|
||||
|
||||
printf("Year of Publication: %d\n", cJSON_GetObjectItemCaseSensitive(child, "publish_year")->child->valueint);
|
||||
printf("Page length: %d\n", cJSON_GetObjectItemCaseSensitive(child, "number_of_pages_median")->valueint);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
char isbn_buf[14];
|
||||
CURLcode res;
|
||||
|
||||
if (2 != argc) {
|
||||
printf("Usage: isbn [isbn]\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* We must initialize cURL
|
||||
*/
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/**
|
||||
* Grab the ISBN from argv
|
||||
*/
|
||||
snprintf(isbn_buf, 14, "%s", argv[1]);
|
||||
|
||||
/**
|
||||
* Setup the output string
|
||||
*/
|
||||
string get_output;
|
||||
init_string(&get_output);
|
||||
|
||||
/**
|
||||
* Perform the get request
|
||||
*/ res = perform_book_get(isbn_buf, &get_output);
|
||||
if (0 != res) {
|
||||
fprintf(stderr, "Failed to perform the get request!\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Now we want to parse the JSON input
|
||||
*/
|
||||
parse_json(&get_output);
|
||||
|
||||
/**
|
||||
* We need to free this string
|
||||
*/
|
||||
free(get_output.buf);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user