sprint 1-alpha
|
00001 /****************************************************************************** 00002 * sprint::archive 00003 * 00004 * Copyright (C) 2002-2011 Paolo Medici <www.pmx.it> 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 * 00020 *******************************************************************************/ 00021 00031 #ifndef _SPRINT_ARCHIVE_H 00032 #define _SPRINT_ARCHIVE_H 00033 00034 #include <cstdio> 00035 #include <cstring> 00036 #include <sprint/sysdef.h> 00037 #include <sprint/container/alias.h> 00038 00039 namespace sprint { 00040 00041 /* -1 reserved for Parse Unknown */ 00042 #define ARCHIVE_OK 0 00043 00045 #define ARCHIVE_EOF -2 00046 00048 #define ARCHIVE_EOS -3 00049 00051 #define ARCHIVE_BOS -4 00052 00054 #define ARCHIVE_ERROR -5 00055 00057 typedef const char *SEMANTHIC[]; 00058 00059 #define PRIVATESEMANTHIC static SEMANTHIC 00060 00064 class BaseArchive { 00065 protected: 00066 00067 char filename[32]; 00068 char relativepath[64]; 00069 00071 BaseArchive *prev; 00072 00074 FILE *fp; 00076 UINT curline; 00077 00079 UINT format; 00081 int level; 00082 00083 protected: 00084 BaseArchive *Push(); 00085 BOOL Pop(); 00086 00087 inline bool IsNested() const 00088 { 00089 return prev!=NULL; 00090 } 00091 00092 public: 00093 00094 BaseArchive(); 00095 ~BaseArchive(); 00096 00098 void Rewind(); 00099 00100 void setpath(const char *path); 00101 00102 void setfilename(const char *file); 00103 00104 char *get_full_pathname(char *buffer); 00105 00107 00108 inline long GetCurPos() { 00109 return ftell(fp); 00110 } 00111 inline long SetCurPos(long pos) { 00112 return fseek(fp, pos, SEEK_SET); 00113 } 00114 00115 inline void DeepLevel() { 00116 level++; 00117 } 00118 inline void RaiseLevel() { 00119 level--; 00120 } 00121 00122 long GetFileSize(); 00123 00124 void move_to_the_end(); 00125 00126 void crop_file(); 00128 00129 inline bool IsValid() const { 00130 return fp!=NULL; 00131 } 00132 00133 void printerror(const char *string); 00134 00136 BOOL close(); 00137 00138 inline UINT GetCurLine() const { 00139 return curline; 00140 } 00141 inline const char *GetCurFile() const { 00142 return filename; 00143 } 00144 00145 }; 00146 00148 class ArchiveOut:public BaseArchive { 00149 const char **semanthic; 00150 public: 00151 00153 const char **set_semanthic(const char **newsemanthic); 00154 00155 BOOL create(const char *file, UINT format); 00156 00157 void writecomment(const char *comment); 00158 void writeversion(); 00159 00161 /*{*/ 00162 void rawwrite(const char *string); 00163 00164 void write(unsigned int key, const char *string); 00165 void write(unsigned int key, unsigned int number); 00166 00168 inline void write(unsigned int key, unsigned long number) { 00169 write(key, (unsigned int) number); 00170 } 00171 00172 void write(unsigned int key, int number); 00173 void writef(unsigned int key, const char *format, ...); 00174 00175 void writeflagalias(unsigned int key, unsigned int value, const char **alias); 00176 00177 void writeflag(unsigned int key, unsigned int flag); 00178 void writebytevector(unsigned int key, unsigned char *, unsigned int size, char separator); 00179 void writevector(unsigned int key, const void *, unsigned int count, unsigned int c_size); 00180 void writehexbytevector(unsigned int key, unsigned char *, int size); 00181 /*}*/ 00182 00183 void create_object(unsigned int key, const char *param); 00184 void close_object(unsigned int key); 00185 00186 /* > da questo punto in poi scrive su un files secondario */ 00187 void include_files(const char *filename); 00188 00189 }; 00190 00192 struct DefineList { 00193 DefineList *next; 00194 char *def; 00195 char *value; 00196 }; 00197 00200 class ArchiveInBase : public BaseArchive { 00202 char multilinesupport; 00203 00204 int skiplevel; /* ToDo: nel caso di ELSE IF END IF ANNIDATI */ 00205 00206 DefineList *dlroot; /* macro */ 00207 00208 // SPLIT CORRENTE (memoria relativa a g_buffer o buffer utente) 00210 char *m_id; 00212 char *m_param; 00213 00214 public: 00215 ArchiveInBase(); 00216 00218 00219 00221 bool open(const char *file); 00222 00223 // riapro il file precedentemente aperto con open 00224 bool Reopen(); 00225 00227 inline void DisableMultilineSupport() { 00228 multilinesupport=0; 00229 }; 00230 inline void EnableMultilineSupport(char multilinechar) { 00231 multilinesupport=multilinechar; 00232 }; 00233 00235 bool Define(const char *def, const char *value); 00236 bool Undefine(const char *def); 00237 const char *IsDefined(const char *def); 00240 00241 00242 char *readnakedline(char *buffer=NULL, unsigned int buffer_size=0); 00243 00244 /* Restituisce un puntatore all'inizio della linea, senza spazi all'inizio, alla fine, 00245 * rimuove i commenti e unisce linee multiple 00246 * @note usa il buffer globale 00247 */ 00248 char *readvalidline(void); 00249 00250 /* legge una linea e rimuove l'endl finali, gli spazi iniziali e i commenti */ 00251 /* legge una linea e salta linee con commenti, e esegue linee con comandi della libreria */ 00256 int read(); 00257 00259 inline const char *id() const { return m_id; } 00261 inline const char *param() const { return m_param; } 00263 bool is(const char *str) const { return !strcmp(m_id, str); } 00264 00265 inline bool successread() { 00266 int ret = read(); 00267 return (ret==ARCHIVE_OK)||(ret==ARCHIVE_BOS); 00268 }; 00269 00270 inline bool successread(int &ret) { 00271 ret = read(); 00272 return (ret==ARCHIVE_OK)||(ret==ARCHIVE_BOS); 00273 }; 00274 00275 00276 bool deep(); 00277 /* legge una linea e riempi l'id e il param (se presente), 00278 restituisce EOF,EOS,OK*/ 00279 00281 int parse(const char **semanthic); 00282 00285 int readparse(char **param, const char **semanthic); 00286 00287 int skip_section_ex(unsigned int *level_item, unsigned int *all_item); 00288 inline int skip_section() 00289 { 00290 return skip_section_ex(NULL, NULL); 00291 } 00292 00293 void script(const char *data); 00294 00295 00296 }; 00297 00298 class ArchiveImporter { 00299 public: 00300 virtual bool Parse(ArchiveInBase *a) = 0; 00301 bool Import(ArchiveInBase *a); 00302 }; 00303 00305 class ArchiveIn:public ArchiveInBase { 00306 const char **semanthic; 00307 public: 00308 00310 const char **set_semanthic(const char **newsemanthic); 00311 00314 inline int parse(char **data) { 00315 return readparse(data, semanthic); 00316 } 00317 }; 00318 00319 00320 /* 00321 00322 void ArchiveConvert(ArchiveOut *out, ArchiveIn *in); 00323 00324 pių che altro serve una callback per la semantica di ingresso e di uscita al 00325 cambio di */ 00326 00327 /***** FILE FORMAT ****/ 00328 #define AF_TEXT 0 00329 #define AF_BINARY 1 00330 #define AF_XML 2 00331 #define AF_JSON 3 00332 00333 /**** FLAGS ****/ 00334 #define FLAG_OPENFORWRITE 0x01 00335 #define FLAG_ROOT 0x02 00336 #define FLAG_BINARY 0x80 00337 00338 #define SIT_UNKNOWN 0 00339 #define SIT_SECTION 1 00340 #define SIT_STRING 2 00341 00342 00343 // C LIke solution (1 pointer) 00344 #define PUSHSEMANTHIC(a,s); const char **__oldsem = (a)->set_semanthic(s); 00345 #define POPSEMANTHIC(a); (a)->set_semanthic(__oldsem); 00346 00347 // C++ Solution (2 pointers) (ma si spera che vengano ottimizzati) 00348 template<class T> 00349 class SemanthicContext { 00350 T m_a; 00351 const char **m_oldsem; 00352 public: 00353 SemanthicContext(T _a, const char **newsemanthic) : 00354 m_a(_a), 00355 m_oldsem(_a->set_semanthic(newsemanthic)) { } 00356 ~SemanthicContext() 00357 { 00358 m_a->set_semanthic(m_oldsem); 00359 } 00360 }; 00361 00362 #define SEMANTHICSCOPE(a,s); sprint::SemanthicContext<typeof(a)> _ctx(a, s); 00363 00364 BOOL ArchiveGenericExport(ArchiveOut *a, const BYTE *priv, const char **semanthic); 00365 00366 BOOL ArchiveGenericImport(ArchiveIn *a, BYTE *priv, const char **semanthic); 00367 00368 void ArchiveSetServerName(const char *name); 00369 00370 } // namespace 00371 00372 #endif 00373