/* * $Id: URLTool.cpp,v 1.1 2005/10/19 14:05:44 ozawa Exp $ * * Copyright 2005- ONGS Inc. All rights reserved. * * author: Masanori OZAWA (ozawa@ongs.co.jp) * version: $Revision: 1.1 $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY ONGS INC ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL ONGS INC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of the ONGS Inc. * */ #include "xdtp.h" #include "URLTool.h" #include "URI.h" #include "URLTool_Nano.h" #include "URLTool_Fetch.h" #ifndef WITHOUT_GDK #include "gdk-pixbuf/gdk-pixbuf.h" #endif using namespace XDTP; URLTool::URLTool() { } URLTool::~URLTool() { } /** * URLで参照するリソースを取得します。 * * @param url リソースを識別するURL * @param buf 取得したバッファへのアドレスを記録する。 * 不要になった段階で free する必要があります。 * @param len 取得したバッファのバイト長。 * @return 成功した場合は true を戻す。 */ bool URLTool::getResource(const Glib::ustring& url, char** buf, int* len) { const URLTYPE type = parseURLType(url); RefPtr pTool = buildURLTool(); if (URL_UNKNOWN == type) { return false; } GByteArray* array = g_byte_array_new(); if (!array) { THROW("Out of memory error!"); } if (!pTool->openResource(url, type)) { g_byte_array_free(array, TRUE); return false; } int read = -1; char data[4096]; try { while (read = pTool->readResource(data, sizeof(data)), 0 < read) { g_byte_array_append(array, (guint8*)data, read); } pTool->closeResource(); } catch (...) { read = -1; } if (0 > read) { g_byte_array_free(array, TRUE); return false; } *buf = (char*)array->data; *len = array->len; g_byte_array_free(array, FALSE); return true; } /** * URLで参照するリソースを取得します。 * * @param url リソースを識別するURL * @param file 出力先ファイル名 * @return 成功した場合は true を戻す。 * 失敗した場合でもファイルが作成されることがあります。 * この場合、ファイルの中身は不定です。 */ bool URLTool::getResource2File(const Glib::ustring& url, const Glib::ustring& file) { const URLTYPE type = parseURLType(url); if (URL_UNKNOWN == type) { return false; } bool bError = false; RefPtr pTool = buildURLTool(); if (!pTool->openResource(url, type)) { return false; } try { Glib::RefPtr io = Glib::IOChannel::create_from_file(file, "w"); io->set_encoding(); // set to binary gssize read = -1; gsize write = 0; char data[4096]; while (read = pTool->readResource(data, sizeof(data)), 0 < read) { if (Glib::IO_STATUS_NORMAL != io->write(data, read, write)) { THROW("I/O error."); } } io->close(); pTool->closeResource(); } catch (...) { bError = true; } return (bError ? false : true); } /** * URLで参照するリソースを取得します。 * * @param url リソースを識別するURL * @param fd 出力先ファイルディスクリプタ * @return 成功した場合は true を戻す。 */ bool URLTool::getResource2File(const Glib::ustring& url, int fd) { const URLTYPE type = parseURLType(url); if (URL_UNKNOWN == type) { return false; } bool bError = false; RefPtr pTool = buildURLTool(); if (!pTool->openResource(url, type)) { return false; } try { int read = -1; char data[4096]; while (read = pTool->readResource(data, sizeof(data)), 0 < read) { if (read != write(fd, data, read)) { THROW("I/O error."); } } pTool->closeResource(); } catch (...) { bError = true; } return (bError ? false : true); } /** * 画像情報のみを取得します。 * * @param url 画像を識別するURL * @param info 情報を格納する IMAGE_INFO 構造体 * @return 取得に成功した場合は true を戻す。 */ bool URLTool::getImageInfo(const Glib::ustring& url, IMAGE_INFO& info) { #ifndef WITHOUT_GDK const URLTYPE type = parseURLType(url); if (URL_FILE == type) { RefPtr uri = URI::parse(url); if (gdk_pixbuf_get_file_info(uri->getPath().c_str(), &info.width, &info.height)) { return true; } } else if (URL_UNKNOWN != type) { bool result = false; std::string tmpfile = Glib::build_filename(Glib::get_tmp_dir(), "_xdtp_temp.XXXXXX"); int fd = Glib::mkstemp(tmpfile); if (0 <= fd) { result = URLTool::getResource2File(url, fd); close(fd); } if (result) { result = (gdk_pixbuf_get_file_info(tmpfile.c_str(), &info.width, &info.height) ? true : false); } if (0 <= fd) { remove(tmpfile.c_str()); } return result; } #endif return false; } /** * リソースの情報を取得します。 * サーバ側の応答コードを利用して情報を取得する場合があるため、 * 実際とは異なる情報を取得する場合があります。 * * @param url リソースを識別するURL * @param info 情報を格納する FILE_INFO 構造体 * @return 取得に成功した場合は true を戻す。 */ bool URLTool::statResource(const Glib::ustring& url, FILE_INFO& info) { RefPtr pTool = buildURLTool(); bool result = pTool->statResourceCore(url, info); return result; } RefPtr URLTool::buildURLTool() { #ifdef WITH_FETCH RefPtr result(new URLTool_Fetch); #else RefPtr result(new URLTool_Nano); #endif return result; } URLTYPE URLTool::parseURLType(const Glib::ustring& url) { URLTYPE result = URL_UNKNOWN; RefPtr uri = URI::parse(url); if (0 >= uri->getScheme().length()) { result = URL_FILE; // no schema's default } else if (uri->isHttpScheme()) { result = URL_HTTP; } else if (uri->isFtpScheme()) { result = URL_FTP; } else if (uri->isFileScheme()) { result = URL_FILE; } return result; }