|  |  | 
 |  |  | #include "bom.hpp" | 
 |  |  |  | 
 |  |  | #include "book.hpp" | 
 |  |  | #include "rapidxml/rapidxml.hpp" | 
 |  |  | #include <cstddef> | 
 |  |  | #include <cstdio> | 
 |  |  | #include <curl/curl.h> | 
 |  |  | #include <fstream> | 
 |  |  | #include <iterator> | 
 |  |  | #include <stdio.h> | 
 |  |  | #include <string> | 
 |  |  | #include <unordered_map> | 
 |  |  | #include <vector> | 
 |  |  |  | 
 |  |  | namespace bom | 
 |  |  | { | 
 |  |  | CURL* curl{NULL}; | 
 |  |  | std::string result; | 
 |  |  |  | 
 |  |  | static size_t my_fwrite(void* buffer, size_t size, size_t nmemb, void* stream) | 
 |  |  | static size_t my_write(void* buffer, std::size_t size, std::size_t nmemb, | 
 |  |  |                        void* stream) | 
 |  |  | { | 
 |  |  |     FILE* out = (FILE*)stream; | 
 |  |  |     if (!out) { | 
 |  |  |         out = tmpfile(); | 
 |  |  |         if (!out) { | 
 |  |  |             return -1; | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |     return fwrite(buffer, size, nmemb, out); | 
 |  |  |     std::string& text = *static_cast<std::string*>(stream); | 
 |  |  |     std::size_t totalsize = size * nmemb; | 
 |  |  |     text.append(static_cast<char*>(buffer), totalsize); | 
 |  |  |     return totalsize; | 
 |  |  | } | 
 |  |  | void updateBom(std::unordered_map<std::string, book::Book>& bs) | 
 |  |  |  | 
 |  |  | void initialise() | 
 |  |  | { | 
 |  |  |     CURL* curl; | 
 |  |  |     CURLcode res; | 
 |  |  |     FILE* f{NULL}; | 
 |  |  |     curl_global_init(CURL_GLOBAL_DEFAULT); | 
 |  |  |     curl = curl_easy_init(); | 
 |  |  |     if (curl) { | 
 |  |  |         curl_easy_setopt(curl, CURLOPT_URL, | 
 |  |  |                          "ftp://ftp.bom.gov.au/anon/gen/fwo/IDN60920.xml"); | 
 |  |  |         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite); | 
 |  |  |         curl_easy_setopt(curl, CURLOPT_WRITEDATA, &f); | 
 |  |  |         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_write); | 
 |  |  |         curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result); | 
 |  |  |         curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); | 
 |  |  |         res = curl_easy_perform(curl); | 
 |  |  |         curl_easy_cleanup(curl); | 
 |  |  |         if (CURLE_OK != res) { | 
 |  |  |             fprintf(stderr, "Curl failed: %d\n", res); | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |     if (f) { | 
 |  |  |         fclose(f); | 
 |  |  | } | 
 |  |  |  | 
 |  |  | void destroy() { curl_global_cleanup(); } | 
 |  |  |  | 
 |  |  | void updateBom(std::unordered_map<std::string, book::Book>& bs) | 
 |  |  | { | 
 |  |  |     CURLcode res; | 
 |  |  |     res = curl_easy_perform(curl); | 
 |  |  |     curl_easy_cleanup(curl); | 
 |  |  |     if (CURLE_OK != res) { | 
 |  |  |         fprintf(stderr, "Curl failed: %d\n", res); | 
 |  |  |     } | 
 |  |  |     curl_global_cleanup(); | 
 |  |  |     rapidxml::xml_document<> d; | 
 |  |  |     d.parse<0>(&result[0]); | 
 |  |  |     rapidxml::xml_node<>* n = d.first_node(); | 
 |  |  |     for (rapidxml::xml_attribute<>* a = n->first_attribute(); a; | 
 |  |  |          a = a->next_attribute()) { | 
 |  |  |         std::cout << a->name() << ": " << a->value() << std::endl; | 
 |  |  |     } | 
 |  |  | } | 
 |  |  | } // namespace bom |