dlvhex
2.5.0
|
00001 /* dlvhex -- Answer-Set Programming with external interfaces. 00002 * Copyright (C) 2005-2007 Roman Schindlauer 00003 * Copyright (C) 2006-2015 Thomas Krennwallner 00004 * Copyright (C) 2009-2016 Peter Schüller 00005 * Copyright (C) 2011-2016 Christoph Redl 00006 * Copyright (C) 2015-2016 Tobias Kaminski 00007 * Copyright (C) 2015-2016 Antonius Weinzierl 00008 * 00009 * This file is part of dlvhex. 00010 * 00011 * dlvhex is free software; you can redistribute it and/or modify it 00012 * under the terms of the GNU Lesser General Public License as 00013 * published by the Free Software Foundation; either version 2.1 of 00014 * the License, or (at your option) any later version. 00015 * 00016 * dlvhex is distributed in the hope that it will be useful, but 00017 * WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 * Lesser General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Lesser General Public 00022 * License along with dlvhex; if not, write to the Free Software 00023 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 00024 * 02110-1301 USA. 00025 */ 00026 00037 #ifdef HAVE_CONFIG_H 00038 #include "config.h" 00039 #endif // HAVE_CONFIG_H 00040 00041 #ifdef HAVE_LIBCURL 00042 00043 #include "dlvhex2/URLBuf.h" 00044 00045 #include <sstream> 00046 #include <cstdlib> 00047 #include <cstring> 00048 00049 #include <curl/curl.h> 00050 00051 DLVHEX_NAMESPACE_BEGIN 00052 00053 URLBuf::URLBuf() 00054 : std::streambuf(), 00055 ibuf(0), 00056 bufsize(0), 00057 easy_handle(0) 00058 { } 00059 00060 URLBuf::URLBuf(const URLBuf&) 00061 : std::streambuf(), 00062 ibuf(0), 00063 bufsize(0), 00064 easy_handle(0) 00065 { } 00066 00067 URLBuf::~URLBuf() 00068 { 00069 if (ibuf) { 00070 free(ibuf); 00071 ibuf = 0; 00072 } 00073 } 00074 00075 00076 void 00077 URLBuf::open(const std::string& url) 00078 { 00079 if (easy_handle == 0) { 00080 easy_handle = curl_easy_init(); 00081 curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, URLBuf::writer); 00082 curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, this); 00083 curl_easy_setopt(easy_handle, CURLOPT_URL, url.c_str()); 00084 } 00085 } 00086 00087 00088 long 00089 URLBuf::responsecode() const 00090 { 00091 return response; 00092 } 00093 00094 00095 size_t 00096 URLBuf::writer(void *ptr, size_t size, size_t nmemb, void *stream) 00097 { 00098 URLBuf* mybuf = reinterpret_cast<URLBuf*>(stream); 00099 return mybuf->write(ptr, size * nmemb); 00100 } 00101 00102 00103 size_t 00104 URLBuf::write(void* ptr, size_t size) 00105 { 00106 if (ibuf == 0) { 00107 // allocate input buffer for the first time 00108 ibuf = (std::streambuf::char_type*) ::malloc(size); 00109 bufsize = 0; 00110 } 00111 else { 00112 // reallocate input buffer 00113 ibuf = (std::streambuf::char_type*) ::realloc(ibuf, bufsize + size); 00114 } 00115 00116 // copy ptr to input buffer 00117 ::memcpy(ibuf + bufsize, ptr, size); 00118 // and increase buffer size 00119 bufsize += size; 00120 00121 // set new input buffer boundaries 00122 setg(ibuf, ibuf, ibuf + bufsize); 00123 00124 return size; 00125 } 00126 00127 00128 std::streambuf::int_type 00129 URLBuf::underflow() 00130 { 00131 if (easy_handle == 0) { 00132 // we received everything 00133 return traits_type::eof(); 00134 } 00135 // empty ibuf -> receive data 00136 else if (gptr() >= egptr()) { 00137 CURLcode res; 00138 00139 // fetch from server 00140 res = curl_easy_perform(easy_handle); 00141 00142 // get return code 00143 curl_easy_getinfo(easy_handle, CURLINFO_RESPONSE_CODE, &response); 00144 00145 // shutdown connection 00146 curl_easy_cleanup(easy_handle); 00147 easy_handle = 0; 00148 00149 if (res != 0) { 00150 std::cerr << curl_easy_strerror(res) << std::endl; 00151 return traits_type::eof(); 00152 } 00153 } 00154 00155 return traits_type::to_int_type(*gptr()); 00156 } 00157 00158 00159 DLVHEX_NAMESPACE_END 00160 #endif 00161 00162 00163 // vim:expandtab:ts=4:sw=4: 00164 // mode: C++ 00165 // End: