latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 2002, 2003, 2004, 2005, 2006 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * This file is part of the LTI-Computer Vision Library (LTI-Lib) 00006 * 00007 * The LTI-Lib is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public License (LGPL) 00009 * as published by the Free Software Foundation; either version 2.1 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * The LTI-Lib is distributed in the hope that it will be 00013 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00014 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with the LTI-Lib; see the file LICENSE. If 00019 * not, write to the Free Software Foundation, Inc., 59 Temple Place - 00020 * Suite 330, Boston, MA 02111-1307, USA. 00021 */ 00022 00023 00024 00025 /*---------------------------------------------------------------- 00026 * project ....: LTI Digital Image/Signal Processing Library 00027 * file .......: ltiURL.h 00028 * authors ....: Jochen Wickel 00029 * organization: LTI, RWTH Aachen 00030 * creation ...: 08.07.02 00031 * revisions ..: $Id: ltiURL.h,v 1.7 2006/02/08 12:55:34 ltilib Exp $ 00032 */ 00033 00034 #ifndef _LTI_URL_H_ 00035 #define _LTI_URL_H_ 00036 00037 #include "ltiConfig.h" 00038 00039 #include "ltiIoObject.h" 00040 #include "ltiVector.h" 00041 #include "ltiImage.h" 00042 #include "ltiTypes.h" 00043 #include <iostream> 00044 #include <fstream> 00045 #include <string> 00046 00047 #ifdef _LTI_WIN32 00048 #include <winsock.h> 00049 #endif 00050 00051 00052 namespace lti { 00053 00054 /** 00055 * Class for retrieving documents identified by an URL. You simply 00056 * give it an URL and call the appropriate get method (PUT's are not 00057 * yet supported. For instance: 00058 * 00059 * \code 00060 * lti::url doc("http://tintas/axiom/axicon.png"); 00061 * if (doc.isOk()) { 00062 * doc.getPNGImage(tmp); 00063 00064 * viewer view; 00065 * view.show(tmp); 00066 * getchar(); 00067 * } else { 00068 * std::cerr << doc.getStatusString() << std::endl; 00069 * } 00070 * \endcode 00071 * 00072 * Unfortunately, I have no idea how to implement http client code 00073 * for Windows. Therefore, this class currently only exists for 00074 * libs compiled for Linux. 00075 * 00076 * Ws2_32.lib is linked (you may need to specify its library in 00077 * Project..Settings..Link..Object/Library Modules.) 00078 */ 00079 class url : public object { 00080 00081 00082 public: 00083 00084 /** 00085 * parameters for the url-object 00086 */ 00087 class parameters { 00088 public: 00089 /** 00090 * default constructor 00091 */ 00092 parameters(); 00093 00094 /** 00095 * copy constructor 00096 */ 00097 parameters(const parameters& other); 00098 00099 /** 00100 * destructor 00101 */ 00102 virtual ~parameters(); 00103 00104 /** 00105 * copy member 00106 */ 00107 parameters& copy(const parameters& other); 00108 00109 /** 00110 * copy data of "other" parameters 00111 */ 00112 parameters& operator=(const parameters& other); 00113 00114 /** 00115 * returns a pointer to a clone of the parameters 00116 */ 00117 virtual parameters* clone() const; 00118 00119 /** 00120 * returns name of this type 00121 */ 00122 const char* getTypeName() const; 00123 00124 /** 00125 * write the parameters in the given ioHandler 00126 * @param handler the ioHandler to be used 00127 * @param complete if true (the default) the enclosing begin/end will 00128 * be also written, otherwise only the data block will be written. 00129 * @return true if write was successful 00130 */ 00131 virtual bool write(ioHandler& handler, 00132 const bool complete=true) const; 00133 00134 /** 00135 * read the parameters from the given ioHandler 00136 * @param handler the ioHandler to be used 00137 * @param complete if true (the default) the enclosing begin/end will 00138 * be also written, otherwise only the data block will be written. 00139 * @return true if write was successful 00140 */ 00141 virtual bool read(ioHandler& handler,const bool complete=true); 00142 00143 # ifdef _LTI_MSC_6 00144 /** 00145 * this function is required by MSVC only, as a workaround for a 00146 * very awful bug, which exists since MSVC V.4.0, and still by 00147 * V.6.0 with all bugfixes (so called "service packs") remains 00148 * there... This method is public due to another bug!, so please 00149 * NEVER EVER call this method directly 00150 */ 00151 bool readMS(ioHandler& handler,const bool complete=true); 00152 00153 /** 00154 * this function is required by MSVC only, as a workaround for a 00155 * very awful bug, which exists since MSVC V.4.0, and still by 00156 * V.6.0 with all bugfixes (so called "service packs") remains 00157 * there... This method is public due to another bug!, so please 00158 * NEVER EVER call this method directly 00159 */ 00160 bool writeMS(ioHandler& handler,const bool complete=true) const; 00161 # endif 00162 00163 // ------------------------ 00164 // the parameters 00165 // ------------------------ 00166 00167 /** 00168 * directory name, which holds the temporary image files. 00169 * Default directory: C:\\TEMP 00170 * This parameter is only for Windows needed not Linux.0 00171 */ 00172 std::string tmpDirectory; 00173 00174 00175 }; 00176 00177 /** 00178 * The type of service that is associated with the URL. 00179 */ 00180 enum serviceType { 00181 UNKNOWN = -1, 00182 HTTP = 0, 00183 FTP = 1, 00184 FILE = 2, 00185 MAXSERVICE = 19 00186 }; 00187 00188 /** 00189 * This class is used to split a URL into its separate fields. 00190 * For example, if you call its constructor with 00191 * "http://ltilib.sourceforge.net:80/index.html", it would 00192 * split it into the service type (http), the hostname 00193 * (ltilib.sourceforge.net), the port (80), and the path 00194 * (/index.html). 00195 */ 00196 class urlFields: public object { 00197 public: 00198 00199 /** 00200 * Default constructor. Is equivalent to using 00201 * "http://localhost/index.html". 00202 */ 00203 urlFields(); 00204 00205 /** 00206 * Constructor. 00207 */ 00208 urlFields(const std::string& u); 00209 00210 /** 00211 * Returns the port number for the URL. If no number is 00212 * specified, the port depends on the service type. 00213 * E.g. its 80 for HTTP, 21 for FTP. 00214 */ 00215 inline int getPort() const { return port; }; 00216 00217 /** 00218 * Returns the hostname. 00219 */ 00220 inline const std::string& getHostname() const { return hostname; }; 00221 00222 /** 00223 * Returns the path. 00224 */ 00225 inline const std::string& getPath() const { return path; }; 00226 00227 /** 00228 * Returns the service type. 00229 */ 00230 inline serviceType getService() const { return service; }; 00231 00232 protected: 00233 int port; 00234 serviceType service; 00235 std::string hostname; 00236 std::string path; 00237 }; 00238 00239 /** 00240 * This is an abstract base class for handling a kind of 00241 * data service. It contains methods for initiating a connection 00242 * given an url and get the most important meta data. A certain 00243 * service handler is created by subclassing this class. 00244 * At present, there is only a HTTP handler which is buried in 00245 * the implementation. 00246 */ 00247 class serviceHandler: public object { 00248 protected: 00249 /** 00250 * Constructor. Subclasses must call this constructor in order 00251 * to set the URL for which this handler is used. 00252 */ 00253 serviceHandler(url& u); 00254 00255 /** 00256 * Returns the input stream for the URL which is handled by 00257 * this object. 00258 */ 00259 std::ifstream* getIn() { return doc.in; }; 00260 00261 /** 00262 * Returns the output stream for the URL which is handled by 00263 * this object. 00264 */ 00265 std::ofstream* getOut() { return doc.out; }; 00266 00267 #ifdef _LTI_WIN32 00268 /** 00269 * Returns the socket used to send/receive bytes (only for windows) 00270 */ 00271 00272 SOCKET getSocket(){return doc.winsock;}; 00273 #endif 00274 00275 public: 00276 /** 00277 * Gets the date of the server reply, may be empty. 00278 * @param date will receive the date in standard ASCII 00279 * notation 00280 * @return true if the date could be retrieved successfully, 00281 * false otherwise. 00282 */ 00283 virtual bool getDate(std::string& date)=0; 00284 00285 /** 00286 * Gets the MIME type description of the document which 00287 * is described by the URL. 00288 * @param type will receive the type description in standard MIME 00289 * notation 00290 * @return true if the type could be retrieved successfully, 00291 * false otherwise. 00292 */ 00293 virtual bool getContentType(std::string& type)=0; 00294 00295 /** 00296 * Gets the length of the document which is described by the URL. 00297 * @param size will receive the size of the document in bytes. 00298 * If this value is below zero, it means that the size is 00299 * unknown. 00300 * @return true if the size could be retrieved successfully, 00301 * false otherwise. 00302 */ 00303 virtual bool getContentLength(int& size)=0; 00304 00305 /** 00306 * Gets a pointer to an input stream which can be used 00307 * for retrieving the data. 00308 * @return true if the stream could be created successfully, 00309 * false otherwise. 00310 */ 00311 virtual bool getDataStream(std::ifstream* &i)=0; 00312 00313 /** 00314 * return the last message set with setStatusString(). This will 00315 * never return 0. If no status-string has been set yet an empty string 00316 * (pointer to a string with only the char(0)) will be returned. 00317 */ 00318 const char* getStatusString() const; 00319 00320 /** 00321 * Returns true if the handler's state is in order and meta-data 00322 * can be inquired. 00323 */ 00324 inline bool isOk() { return ok; }; 00325 00326 protected: 00327 url& doc; 00328 00329 bool ok; 00330 00331 /** 00332 * set a status string. 00333 * 00334 * @param msg the const string to be reported next time by 00335 * getStatusString(). The given string will be copied. 00336 * This message will be usually set within the apply methods to indicate 00337 * an error cause. 00338 * @param msg2 another message string, which is simply appended 00339 * to the first one. 00340 */ 00341 void setStatusString(const char* msg, const char *msg2=0); 00342 00343 std::string status; 00344 }; 00345 00346 /** 00347 * The kind of data type that is expected for reading and 00348 * writing ioObjects. 00349 */ 00350 enum dataType { 00351 RAW = 0, 00352 CONFIG = 1, 00353 LISP = 2, 00354 MAXDATA = 9 00355 }; 00356 00357 /** 00358 * Constructor. Creates a new connection to the URL given as 00359 * argument. If the connection could be created, the function 00360 * isOk returns true. Otherwise, it returns false. If the 00361 * connection failed, the cause can be inquired by calling 00362 * getStatusString. 00363 */ 00364 url(const std::string &n); 00365 00366 /** 00367 * Destructor. Closes the network connection and deletes all 00368 * allocated data structures. 00369 */ 00370 ~url(); 00371 00372 /** 00373 * Returns true if so far all operations have been successful. 00374 */ 00375 bool isOk(); 00376 00377 /** 00378 * set url's parameters. 00379 * This member makes a copy of <em>theParam</em>: the url 00380 * will keep its own copy of the parameters! 00381 * @return true if successful, false otherwise 00382 */ 00383 virtual bool setParameters(const parameters& theParam); 00384 00385 /** 00386 * returns the current parameters 00387 */ 00388 const parameters& getParameters() const; 00389 00390 /** 00391 * Retrieves the URL as text document. This only works if 00392 * the document is of MIME type "text/...". 00393 * @return true iff the document could be retrieved successfully. 00394 */ 00395 bool get(std::string& data); 00396 00397 /** 00398 * Retrieves the URL as binary Data written in data 00399 * @return true iff the document could be retrieved successfully. 00400 */ 00401 bool get(vector<ubyte>& data); 00402 00403 /** 00404 * not implemented yet 00405 */ 00406 bool get(ioObject& data, dataType fmt); 00407 00408 # if defined(HAVE_LIBPNG) || defined(HAVE_LOCALPNG) 00409 /** 00410 * Retrieves the URL as binary Data written in data 00411 * @return true iff the document could be retrieved successfully. 00412 */ 00413 bool getPNGImage(image& data); 00414 # endif 00415 00416 00417 # if defined(HAVE_LIBJPEG) || defined(HAVE_LOCALJPEG) 00418 /** 00419 * Retrieves the URL as binary Data written in data 00420 * @return true iff the document could be retrieved successfully. 00421 */ 00422 bool getJPGImage(image& data); 00423 # endif 00424 00425 /** 00426 * Retrieves the URL as binary Data written in data 00427 * @return true iff the document could be retrieved successfully. 00428 */ 00429 bool getBMPImage(image& data); 00430 00431 /** 00432 * Not implemented yet. 00433 */ 00434 bool put(const std::string& data); 00435 00436 /** 00437 * Not implemented yet. 00438 */ 00439 bool put(const vector<ubyte>& data); 00440 00441 00442 /** 00443 * Not implemented yet. 00444 */ 00445 bool put(const ioObject& data, dataType fmt); 00446 00447 /** 00448 * Not implemented yet. 00449 */ 00450 bool putPNGImage(const image& data); 00451 00452 /** 00453 * Returns the input stream that is used for reading the 00454 * document.(linux only) 00455 */ 00456 std::istream& getInputStream(); 00457 00458 /** 00459 * Returns the output stream that is used for writing the 00460 * document. (linux only) 00461 */ 00462 std::ostream& getOutputStream(); 00463 00464 /** 00465 * Returns the path component of this URL. 00466 */ 00467 const std::string& getPath() const; 00468 00469 /** 00470 * return the last message set with setStatusString(). This will 00471 * never return 0. If no status-string has been set yet an empty string 00472 * (pointer to a string with only the char(0)) will be returned. 00473 */ 00474 const char* getStatusString() const; 00475 00476 protected: 00477 00478 serviceHandler* handler; 00479 00480 bool initConnect(); 00481 bool openStreams(); 00482 00483 /** 00484 * set a status string. 00485 * 00486 * @param msg the const string to be reported next time by 00487 * getStatusString(). The given string will be copied. 00488 * This message will be usually set within the apply methods to indicate 00489 * an error cause. 00490 * @param msg2 another message string, which is simply appended 00491 * to the first one. 00492 */ 00493 void setStatusString(const char* msg, const char *msg2=0); 00494 00495 private: 00496 00497 /** 00498 * current parameters. 00499 */ 00500 parameters* params; 00501 00502 std::ifstream* in; 00503 std::ofstream* out; 00504 00505 int sock; 00506 dataType dtype; 00507 urlFields fields; 00508 std::string status; 00509 std::string defaultType; 00510 friend class serviceHandler; 00511 00512 #ifdef _LTI_WIN32 00513 00514 SOCKET winsock; 00515 00516 /** 00517 * create unique name for temporary image file consisting 00518 * of path, pid, instance number and original name 00519 */ 00520 bool getTempFilePath(std::string& filepath); 00521 00522 /** 00523 * receive binary data by connected socket and write into out file 00524 * (httpHeader has already been read) 00525 */ 00526 bool receiveAndWriteFile(std::ofstream& out); 00527 00528 /** 00529 * used for debug only 00530 */ 00531 int getFileSize(std::string fileName); 00532 00533 /** 00534 * used to create unique temporary filename 00535 */ 00536 static int instanceNumber; 00537 #endif 00538 00539 }; 00540 } 00541 00542 #endif