dlvhex  2.5.0
src/URLBuf.cpp
Go to the documentation of this file.
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: