curl.h 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. #pragma once
  2. #include <cstdlib>
  3. #include <sstream>
  4. #include <string>
  5. #include <string_view>
  6. #include <curl/curl.h>
  7. #include <jvalidate/adapter.h>
  8. #include <jvalidate/compat/expected.h>
  9. #include <jvalidate/forward.h>
  10. #include <jvalidate/uri.h>
  11. namespace jvalidate {
  12. inline size_t transfer_to_buffer(char * data, size_t size, size_t nmemb, void * userdata) {
  13. std::stringstream & ss = *static_cast<std::stringstream *>(userdata);
  14. size_t const actual_size = size * nmemb;
  15. ss << std::string_view(data, actual_size);
  16. return actual_size;
  17. }
  18. template <typename JSON>
  19. auto curl_get(jvalidate::URI const & uri, JSON & out) noexcept
  20. -> detail::expected<void, std::string> {
  21. using jvalidate::adapter::load_file;
  22. using jvalidate::adapter::load_stream;
  23. if (uri.scheme().starts_with("http")) {
  24. std::stringstream ss;
  25. if (CURL * curl = curl_easy_init(); curl) {
  26. curl_easy_setopt(curl, CURLOPT_URL, uri.c_str());
  27. curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
  28. curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ss);
  29. curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &transfer_to_buffer);
  30. CURLcode const res = curl_easy_perform(curl);
  31. curl_easy_cleanup(curl);
  32. if (res == CURLE_OK) {
  33. return load_stream(ss, out);
  34. }
  35. }
  36. return detail::unexpected("curl error");
  37. }
  38. if (uri.scheme() == "file") {
  39. return load_file(uri.resource(), out);
  40. }
  41. return detail::unexpected("unknown scheme");
  42. }
  43. }