|
1 | | -// The MIT License (MIT) |
| 1 | +// The MIT License ( MIT ) |
2 | 2 | // |
3 | | -// Copyright (c) 2016 Darrell Wright |
| 3 | +// Copyright ( c ) 2016 Darrell Wright |
4 | 4 | // |
5 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy |
6 | 6 | // of this software and associated documentation files( the "Software" ), to deal |
|
20 | 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
21 | 21 | // SOFTWARE. |
22 | 22 |
|
| 23 | +#include <boost/algorithm/string/predicate.hpp> |
| 24 | +#include <boost/optional.hpp> |
| 25 | +#include <boost/utility/string_view.hpp> |
23 | 26 | #include <cstdlib> |
| 27 | +#include <curl/curl.h> |
24 | 28 | #include <fstream> |
| 29 | +#include <string> |
| 30 | +#include <memory> |
25 | 31 | #include <iostream> |
26 | 32 |
|
27 | 33 | #include "json_to_cpp.h" |
| 34 | +namespace { |
| 35 | + size_t callback( char const * in, size_t const size, size_t const num, std::string * const out ) { |
| 36 | + assert( out ); |
| 37 | + size_t totalBytes = size * num; |
| 38 | + out->append( in, totalBytes ); |
| 39 | + return totalBytes; |
| 40 | + } |
| 41 | + |
| 42 | + boost::optional<std::string> download( boost::string_view url ) { |
| 43 | + struct curl_slist *headers = nullptr; |
| 44 | + curl_slist_append( headers, "Accept: application/json" ); |
| 45 | + curl_slist_append( headers, "Content-Type: application/json" ); |
| 46 | + curl_slist_append( headers, "charsets: utf-8" ); |
| 47 | + |
| 48 | + CURL* curl = curl_easy_init( ); |
| 49 | + if( !curl ) { |
| 50 | + return boost::none; |
| 51 | + } |
| 52 | + curl_easy_setopt( curl, CURLOPT_HTTPHEADER, headers ); |
| 53 | + curl_easy_setopt( curl, CURLOPT_HTTPGET, 1 ); |
| 54 | + curl_easy_setopt( curl, CURLOPT_HTTPHEADER, headers); |
| 55 | + // Set remote URL. |
| 56 | + curl_easy_setopt( curl, CURLOPT_URL, url.data( ) ); |
| 57 | + |
| 58 | + // Don't wait forever, time out after 10 seconds. |
| 59 | + curl_easy_setopt( curl, CURLOPT_TIMEOUT, 15 ); |
| 60 | + |
| 61 | + // Follow HTTP redirects if necessary. |
| 62 | + curl_easy_setopt( curl, CURLOPT_FOLLOWLOCATION, 1L ); |
| 63 | + |
| 64 | + // Response information. |
| 65 | + int httpCode = 0; |
| 66 | + std::string httpData; |
| 67 | + |
| 68 | + // Hook up data handling function. |
| 69 | + curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, callback ); |
| 70 | + |
| 71 | + // Hook up data container ( will be passed as the last parameter to the |
| 72 | + // callback handling function ). Can be any pointer type, since it will |
| 73 | + // internally be passed as a void pointer. |
| 74 | + curl_easy_setopt( curl, CURLOPT_WRITEDATA, &httpData ); |
| 75 | + |
| 76 | + // Run our HTTP GET command, capture the HTTP response code, and clean up. |
| 77 | + curl_easy_perform( curl ); |
| 78 | + curl_easy_getinfo( curl, CURLINFO_RESPONSE_CODE, &httpCode ); |
| 79 | + curl_easy_cleanup( curl ); |
| 80 | + |
| 81 | + if( httpCode != 200 ) { |
| 82 | + std::cerr << "Couldn't GET from " << url << '\n'; |
| 83 | + return boost::none; |
| 84 | + } |
| 85 | + |
| 86 | + return httpData; |
| 87 | + } |
| 88 | + |
| 89 | + bool is_url( boost::string_view path ) { |
| 90 | + return boost::starts_with( path.data( ), "http://" ) || boost::starts_with( path.data( ), "https://" ); |
| 91 | + } |
| 92 | +} // namespace anonymous |
28 | 93 |
|
29 | 94 | int main( int argc, char ** argv ) { |
30 | 95 | using namespace daw::json_to_cpp; |
31 | | - |
32 | | - std::ifstream in_file; |
33 | | - in_file.open( argv[1] ); |
34 | | - if( !in_file ) { |
35 | | - std::cerr << "Must supply valid json file on commandline\n"; |
| 96 | + if( argc != 2 ) { |
| 97 | + std::cerr << "Must supply a url or a file as the json source\n"; |
36 | 98 | exit( EXIT_FAILURE ); |
37 | 99 | } |
38 | | - std::string json_blob; |
39 | | - std::copy( std::istream_iterator<char>{ in_file }, std::istream_iterator<char>{ }, std::back_inserter( json_blob ) ); |
40 | | - in_file.close( ); |
| 100 | + std::string const uri{ argv[1] }; |
| 101 | + std::string json_str; |
| 102 | + if( is_url( uri ) ) { |
| 103 | + auto tmp = download( uri ); |
| 104 | + if( tmp ) { |
| 105 | + json_str = *tmp; |
| 106 | + } else { |
| 107 | + std::cerr << "Could not download json data from '" << uri << "'\n"; |
| 108 | + exit( EXIT_FAILURE ); |
| 109 | + } |
| 110 | + } else { |
| 111 | + std::ifstream in_file; |
| 112 | + in_file.open( argv[1] ); |
| 113 | + if( !in_file ) { |
| 114 | + std::cerr << "Must supply valid json file on commandline\n"; |
| 115 | + exit( EXIT_FAILURE ); |
| 116 | + } |
| 117 | + std::copy( std::istream_iterator<char>{ in_file }, std::istream_iterator<char>{ }, std::back_inserter( json_str ) ); |
| 118 | + in_file.close( ); |
| 119 | + } |
41 | 120 | config_t config{ }; |
42 | | - generate_cpp( json_blob, std::cout, config ); |
| 121 | + generate_cpp( json_str, std::cout, config ); |
43 | 122 | std::cout << std::endl; |
44 | 123 |
|
45 | 124 | return EXIT_SUCCESS; |
|
0 commit comments