latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 2001, 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 * project ....: LTI Digital Image/Signal Processing Library 00026 * file .......: ltiBinaryStreamHandler.h 00027 * authors ....: Pablo Alvarado, Jochen Wickel 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 18.05.2001 00030 * revisions ..: $Id: ltiBinaryStreamHandler.h,v 1.6 2006/02/08 12:09:10 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_BINARY_STREAM_HANDLER_H_ 00034 #define _LTI_BINARY_STREAM_HANDLER_H_ 00035 00036 00037 #include <string> 00038 #include <iostream> 00039 #include <stack> 00040 #include "ltiObject.h" 00041 #include "ltiIoHandler.h" 00042 00043 namespace lti { 00044 /** 00045 * Binary stream handler. 00046 * 00047 * The binaryStreamHandler class offer an interface for the functor 00048 * parameters and other classes to read() and write() them in a 00049 * binary format. 00050 * 00051 * The advantage of the binary format is that the produced files are 00052 * smaller, which at the same time implies shorter times to read or write 00053 * the data. 00054 * 00055 * The disadvange is that the produced files cannot be easily edited. If 00056 * you need this, you should still use the lti::lispStreamHandler. 00057 * 00058 * \warning Do not forget to open your streams in binary mode. If you 00059 * create them as ASCII streams, the data can be corrupted. 00060 * 00061 * Example: 00062 * \code 00063 * // the binary stream formatting object 00064 * lti::binaryStreamHandler bsh; 00065 * 00066 * // Write example: 00067 * 00068 * // open a stream in binary mode 00069 * std::ofstream out("testfile.bin",std::ios_base::binary); 00070 * 00071 * // tell the binary stream handler to use the given stream 00072 * bsh.use(out); 00073 * 00074 * lti::write(bsh,"anInteger",5); 00075 * lti::write(bsh,"aString","hello world"); 00076 * 00077 * out.close(); 00078 * 00079 * // Read example 00080 * 00081 * // Open a stream in binary mode 00082 * std::ifstream in("testfile.bin",std::ios_base::binary); 00083 * 00084 * bsh.use(in); 00085 * int i; 00086 * lti::read(bsh,"anInteger",i); 00087 * 00088 * std::string str; 00089 * lti::read(bsh,"aString",str); 00090 * 00091 * in.close(); 00092 * \endcode 00093 * 00094 * @bug: An intrinsic bug for the binary stream handler was found 00095 * (2004-02-03). There are some cases in which the tryXXX methods will 00096 * success (return true), even if the searched token is not present. Some 00097 * rules need to be defined to avoid problems (indirectly the currently used 00098 * formats avoid these cases), but a more detailed revision of the whole 00099 * handler has to be done. 00100 * 00101 * @ingroup gStorable 00102 */ 00103 class binaryStreamHandler : public ioHandler { 00104 public: 00105 /** 00106 * default constructor 00107 */ 00108 binaryStreamHandler(); 00109 00110 /** 00111 * default constructor. 00112 * Please ensure that the given stream was opened with the 00113 * std::ios_base::binary flag! 00114 */ 00115 binaryStreamHandler(std::ostream& aStream); 00116 00117 /** 00118 * default constructor. 00119 * Please ensure that the given stream was opened with the 00120 * std::ios_base::binary flag! 00121 */ 00122 binaryStreamHandler(std::istream& aStream); 00123 00124 /** 00125 * default constructor. 00126 * This constructor uses the given string 00127 * as input. 00128 * Note that the given string is NOT a filename, but a string containing 00129 * the data "stream". 00130 * This is useful especially for the JNI. 00131 */ 00132 binaryStreamHandler(const char *aStream); 00133 00134 /** 00135 * copy constructor 00136 */ 00137 binaryStreamHandler(const binaryStreamHandler& other); 00138 00139 /** 00140 * destructor 00141 */ 00142 virtual ~binaryStreamHandler(); 00143 00144 /** 00145 * indicate the output stream to be used. 00146 * Please ensure that the given stream was opened with the 00147 * std::ios_base::binary flag! 00148 */ 00149 void use(std::ostream& aStream); 00150 00151 /** 00152 * indicate the input stream to be used. 00153 * Please ensure that the given stream was opened with the 00154 * std::ios_base::binary flag! 00155 */ 00156 void use(std::istream& aStream); 00157 00158 /** 00159 * returns the name of this type ("binaryStreamHandler") 00160 */ 00161 virtual const char* getTypeName() const; 00162 00163 /** 00164 * copy data of "other" functor. 00165 * @param other the functor to be copied 00166 * @return a reference to this functor object 00167 */ 00168 binaryStreamHandler& copy(const binaryStreamHandler& other); 00169 00170 /** 00171 * returns a pointer to a clone of this functor. 00172 */ 00173 virtual ioHandler* clone() const; 00174 00175 /** 00176 * the begin token or tokens: here a "(". 00177 * 00178 */ 00179 virtual bool writeBegin(); 00180 00181 /** 00182 * the end token or tokens: here a ")". 00183 */ 00184 virtual bool writeEnd(); 00185 00186 /** 00187 * the begin token or tokens: here a "(" 00188 */ 00189 virtual bool readBegin(); 00190 00191 /** 00192 * the end token or tokens: here a ")" 00193 */ 00194 virtual bool readEnd(); 00195 00196 /** @name write members 00197 */ 00198 //@{ 00199 /** 00200 * write a std::string. 00201 * This method will write just the string if it does not contain spaces. 00202 * Otherwise the string will be enclosed by quotes. 00203 */ 00204 virtual bool write(const std::string& data); 00205 00206 /** 00207 * write a character string. 00208 * This method will write just the string if it does not contain spaces. 00209 * Otherwise the string will be enclosed by quotes. 00210 */ 00211 virtual bool write(const char* data); 00212 00213 /** 00214 * write a double value 00215 */ 00216 virtual bool write(const double& data); 00217 00218 /** 00219 * write a float value 00220 */ 00221 virtual bool write(const float& data); 00222 00223 /** 00224 * write an integer value 00225 */ 00226 virtual bool write(const int& data); 00227 00228 /** 00229 * write an unsigned integer value 00230 */ 00231 virtual bool write(const unsigned int& data); 00232 00233 /** 00234 * write a char 00235 */ 00236 virtual bool write(const char& data); 00237 00238 /** 00239 * write an 8-bit signed value 00240 */ 00241 virtual bool write(const byte& data); 00242 00243 /** 00244 * write a unsigned 8-bit value 00245 */ 00246 virtual bool write(const ubyte& data); 00247 00248 /** 00249 * write a boolean 00250 */ 00251 virtual bool write(const bool& data); 00252 00253 /** 00254 * write a long 00255 */ 00256 virtual bool write(const long& data); 00257 00258 /** 00259 * write an unsigned long 00260 */ 00261 virtual bool write(const unsigned long& data); 00262 00263 /** 00264 * write a short 00265 */ 00266 virtual bool write(const short& data); 00267 00268 /** 00269 * write an unsigned short 00270 */ 00271 virtual bool write(const unsigned short& data); 00272 //@} 00273 00274 /** @name read members 00275 */ 00276 //@{ 00277 /** 00278 * read a std::string 00279 */ 00280 virtual bool read(std::string& data); 00281 00282 /** 00283 * read a double value 00284 */ 00285 virtual bool read(double& data); 00286 00287 /** 00288 * read a float value 00289 */ 00290 virtual bool read(float& data); 00291 00292 /** 00293 * read an integer value 00294 */ 00295 virtual bool read(int& data); 00296 00297 /** 00298 * read an unsigned int value 00299 */ 00300 virtual bool read(unsigned int& data); 00301 00302 /** 00303 * read a char value 00304 */ 00305 virtual bool read(char& data); 00306 00307 /** 00308 * read a char value 00309 */ 00310 virtual bool read(byte& data); 00311 00312 /** 00313 * read an ubyte value 00314 */ 00315 virtual bool read(ubyte& data); 00316 00317 /** 00318 * read a boolan 00319 */ 00320 virtual bool read(bool& data); 00321 00322 /** 00323 * read a long 00324 */ 00325 virtual bool read(long& data); 00326 00327 /** 00328 * read an unsigned long 00329 */ 00330 virtual bool read(unsigned long& data); 00331 00332 /** 00333 * read a short 00334 */ 00335 virtual bool read(short& data); 00336 00337 /** 00338 * read an unsigned short 00339 */ 00340 virtual bool read(unsigned short& data); 00341 //@} 00342 00343 /** 00344 * write a std::string 00345 */ 00346 virtual bool writeSymbol(const std::string& data); 00347 00348 /** 00349 * read a symbol in the given std::string 00350 */ 00351 virtual bool readSymbol(std::string& data); 00352 00353 /** 00354 * try to read the given symbol from the handler. 00355 * If present, returns true and the token is removed from the 00356 * handler, if not present returns false and leaves the stream as 00357 * is... 00358 * @param data the symbol to be readed 00359 */ 00360 virtual bool trySymbol(const std::string& data); 00361 00362 /** 00363 * write comment writes the input data without any preprocessing, 00364 * just ensuring that the comment format is given 00365 */ 00366 virtual bool writeComment(const std::string& data); 00367 00368 /** 00369 * write comment writes the input data without any preprocessing, 00370 * just ensuring that the comment format is given 00371 */ 00372 virtual bool writeComment(const char* data); 00373 00374 /** 00375 * try to read the begin token from the handler. 00376 * If present, returns true and the token is removed from the 00377 * handler, if not present returns false and leaves the handle as 00378 * it was before calling this member... 00379 */ 00380 virtual bool tryBegin(); 00381 00382 /** 00383 * try to read the end token from the handler. 00384 * If present, returns true and the token is removed from the 00385 * handler, if not present returns false and leaves the handle as 00386 * it was before calling this member... 00387 * This is usually used when reading lists of data, where the number of 00388 * elements is unknown. 00389 */ 00390 virtual bool tryEnd(); 00391 00392 /** 00393 * write spaces (default value 1). 00394 * A space-token is a char with value 32. 00395 */ 00396 virtual bool writeSpaces(const int& s=1); 00397 00398 /** 00399 * write end of line 00400 */ 00401 virtual bool writeEOL(); 00402 00403 /** 00404 * write key/value separator. 00405 * In this case the key/value separator is a space 00406 */ 00407 virtual bool writeKeyValueSeparator(); 00408 00409 /** 00410 * write key/value separator. 00411 * In this case the data separator is a space 00412 */ 00413 virtual bool writeDataSeparator(); 00414 00415 /** 00416 * write key/value separator 00417 * A space is expected 00418 */ 00419 virtual bool readKeyValueSeparator(); 00420 00421 /** 00422 * write key/value separator 00423 * A space is expected 00424 */ 00425 virtual bool readDataSeparator(); 00426 00427 /** 00428 * if the input stream is at the end of file return true, otherwise false 00429 * if the stream hasn't been set yet, this function also returns true. 00430 */ 00431 virtual bool eof(); 00432 00433 /** 00434 * restore all the information in the handler taken in the actual 00435 * level. If "complete" is true, the begin-token is also restored 00436 */ 00437 virtual bool restoreLevel(); 00438 00439 protected: 00440 00441 /** 00442 * pointer to the input stream 00443 */ 00444 std::istream* inStream; 00445 00446 /** 00447 * the input stream will be cached into this string 00448 */ 00449 std::string inString; 00450 00451 /** 00452 * actual reading position in the input string 00453 */ 00454 std::string::size_type inStringPos; 00455 00456 /** 00457 * pointer to the output stream 00458 */ 00459 std::ostream* outStream; 00460 00461 /** 00462 * flag to control spaces supression (for example, there is no need for 00463 * spaces between parenthesis) 00464 */ 00465 bool supressSpaces; 00466 00467 /** 00468 * flag to indicate if an EOL is needed 00469 */ 00470 bool tryEOL; 00471 00472 /** 00473 * Tokens 00474 * 00475 * This system requires a complete revision! 00476 */ 00477 enum eTokenId { 00478 BeginToken, 00479 EndToken, 00480 SymbolToken, 00481 StringToken, 00482 ErrorToken 00483 }; 00484 00485 /** 00486 * read next token from the input string or from the input stream 00487 * @see getNextTokenFromString. 00488 */ 00489 eTokenId getNextToken(const bool justTry = false); 00490 00491 void putBackupToken(); 00492 00493 void checkBuffer(int newSize); 00494 00495 eTokenId lastToken; 00496 00497 inline eTokenId char2token(char x); 00498 00499 std::stack<eTokenId> backupTokens; 00500 std::stack<const std::string*> backupStrings; 00501 00502 std::string lastString; 00503 00504 char *buffer; 00505 int bufSize; 00506 00507 }; 00508 00509 } 00510 00511 #endif