00001 /******************************************************************************* 00002 00003 Copyright (C) 2007 by Brendon Costa 00004 00005 This library is free software; you can redistribute it and/or modify 00006 it under the terms of the "LGPL Like" License defined in the file COPYING 00007 that should have been distributed along with this source. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 You should have received a copy of the "LGPL Like" License 00014 along with this library; see the file COPYING. if not, it can be 00015 obtained from the EDoc++ website: 00016 http://edoc.sourceforge.net/license.html 00017 00018 *******************************************************************************/ 00019 #ifndef EDOC_TEXTPERSISTENCE_H 00020 #define EDOC_TEXTPERSISTENCE_H 00021 00022 #include "EDoc/stdint.h" 00023 #include "EDoc/PersistenceIFace.h" 00024 00025 #include <string> 00026 #include <fstream> 00027 00028 namespace EDoc 00029 { 00030 //=========================================================================== 00031 /** \brief An implementation of PersistenceIFace for writing to text files. 00032 * 00033 * This implementation of PersistenceIFace was created primarily for 00034 * debugging purposes. The files it generates are orders of magnitude larger 00035 * than the BinaryPersistence class, however the format it uses provides key 00036 * name, type and value validation upon reading. It also provides ability to 00037 * write in a highly verbose mode where whenever an integer index is written 00038 * to the file it will also write an un-used string that shows which data 00039 * type that integer indexes. This makes reading .edc files mush easier. 00040 * 00041 * From the persistence_data.h file this will use the macros: 00042 * - BJC_PERSIST_START_KEY_CHAR '$' 00043 * - BJC_PERSIST_FINISH_KEY_CHAR ':' 00044 * - BJC_PERSIST_COMMENT_CHAR '#' 00045 * . 00046 * 00047 * to define the delimiters to use for identifying the various fields of a 00048 * data item. The default format looks something like: 00049 * 00050 * \code 00051 * # Comment 00052 * $KeyName1: value 00053 * $KeyName2: int_value Ignored Debugging Text 00054 * \endcode 00055 * 00056 * This limits the string to be saved to string that only contain text values 00057 * and NOT CR/LF characters. This isnt a problem for EDoc currently but may 00058 * in the future be replaced with a format where the value is a string 00059 * escaped using standard unix like escape sequence conventions (i.e. based 00060 * on backslash char). 00061 */ 00062 class TextPersistence : public PersistenceIFace 00063 { 00064 public: 00065 00066 //------------------------------------------------------------------------ 00067 /** \brief Create an instance that represents a text file for reading 00068 * OR writing (But not both at once). 00069 * 00070 * Note: This does not open the file for reading/writing but just creates 00071 * an instance of this class that is prepared for reading/writing to the 00072 * file. 00073 * 00074 * \param read If true then the file is considered an input file and can 00075 * only be used for reading. Otherwise it will be considered an output 00076 * file and will only be available for writing to. 00077 * 00078 * \param filename The name of the file to open. 00079 */ 00080 TextPersistence(bool read, std::string filename); 00081 00082 //------------------------------------------------------------------------ 00083 /** \brief Closes the file upon destruction. 00084 */ 00085 virtual ~TextPersistence(); 00086 00087 //------------------------------------------------------------------------ 00088 /** \brief See PersistenceIFace::Open() 00089 */ 00090 virtual void Open(); 00091 00092 //------------------------------------------------------------------------ 00093 /** \brief See PersistenceIFace::Close() 00094 */ 00095 virtual void Close(); 00096 00097 //------------------------------------------------------------------------ 00098 /** \brief See PersistenceIFace::ReadString() 00099 */ 00100 virtual std::string ReadString(const char* key); 00101 00102 //------------------------------------------------------------------------ 00103 /** \brief See PersistenceIFace::ReadBoolean() 00104 */ 00105 virtual bool ReadBoolean(const char* key); 00106 00107 //------------------------------------------------------------------------ 00108 /** \brief See PersistenceIFace::ReadUInt8() 00109 */ 00110 virtual uint8_t ReadUInt8(const char* key); 00111 00112 //------------------------------------------------------------------------ 00113 /** \brief See PersistenceIFace::ReadInt32() 00114 */ 00115 virtual int32_t ReadInt32(const char* key); 00116 00117 //------------------------------------------------------------------------ 00118 /** \brief See PersistenceIFace::ReadUInt32() 00119 */ 00120 virtual uint32_t ReadUInt32(const char* key); 00121 00122 //------------------------------------------------------------------------ 00123 /** \brief See PersistenceIFace::ReadRecordType() 00124 */ 00125 virtual uint8_t ReadRecordType(); 00126 00127 00128 //------------------------------------------------------------------------ 00129 /** \brief See PersistenceIFace::WriteString() 00130 */ 00131 virtual void WriteString(const char* key, std::string value); 00132 00133 //------------------------------------------------------------------------ 00134 /** \brief See PersistenceIFace::WriteBoolean() 00135 */ 00136 virtual void WriteBoolean(const char* key, bool value); 00137 00138 //------------------------------------------------------------------------ 00139 /** \brief See PersistenceIFace::WriteUInt8() 00140 */ 00141 virtual void WriteUInt8(const char* key, uint8_t value); 00142 00143 //------------------------------------------------------------------------ 00144 /** \brief See PersistenceIFace::WriteInt32() 00145 */ 00146 virtual void WriteInt32(const char* key, int32_t value); 00147 00148 //------------------------------------------------------------------------ 00149 /** \brief See PersistenceIFace::WriteUInt32() 00150 */ 00151 virtual void WriteUInt32(const char* key, uint32_t value); 00152 00153 //------------------------------------------------------------------------ 00154 /** \brief See PersistenceIFace::WriteUInt32Debug() 00155 */ 00156 virtual void WriteUInt32Debug(const char* key, uint32_t value, 00157 std::string debug_text); 00158 00159 //------------------------------------------------------------------------ 00160 /** \brief See PersistenceIFace::WriteInt32Debug() 00161 */ 00162 virtual void WriteInt32Debug(const char* key, int32_t value, 00163 std::string debug_text); 00164 00165 //------------------------------------------------------------------------ 00166 /** \brief See PersistenceIFace::WriteRecordType() 00167 */ 00168 virtual void WriteRecordType(uint8_t value); 00169 00170 //------------------------------------------------------------------------ 00171 00172 private: 00173 00174 //------------------------------------------------------------------------ 00175 /** \brief Returns true if the given string contains any characters that 00176 * are not whitespaces. 00177 */ 00178 static bool ContainsData(const std::string& data); 00179 00180 //------------------------------------------------------------------------ 00181 /** \brief Reads a line of data extracting the value string for that 00182 * line. 00183 * 00184 * This will also validate the type and key throwing an exception if the 00185 * data is not valid. 00186 */ 00187 std::string ReadValue(const char* key_in, const char* type_in); 00188 00189 //------------------------------------------------------------------------ 00190 /** \brief Reads the next line of data from the file. 00191 * 00192 * Performs no processing of the data but may use key_in and type_in for 00193 * debugging purposes if an EOF is encountered. 00194 */ 00195 std::string GetNextLine(const char* key_in = "", 00196 const char* type_in = ""); 00197 00198 //------------------------------------------------------------------------ 00199 /** \brief The file stream used for writing/reading to/from. 00200 */ 00201 std::fstream file; 00202 00203 //------------------------------------------------------------------------ 00204 /** \brief True if opened for reading. 00205 */ 00206 bool reading; 00207 00208 //------------------------------------------------------------------------ 00209 /** \brief Current number of lines read from the file. 00210 * 00211 * Used primarily in providing more useful debugging information. 00212 */ 00213 size_t line_count; 00214 00215 //------------------------------------------------------------------------ 00216 /** \brief Name of file being operated on. 00217 */ 00218 std::string filename; 00219 00220 //------------------------------------------------------------------------ 00221 00222 }; 00223 //=========================================================================== 00224 00225 } 00226 00227 00228 #endif // EDOC_TEXTPERSISTENCE_H