00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <errno.h>
00005 #include "engine/thread_obj.h"
00006 #include "tools/assert.h"
00007 #include "tools/log.h"
00008 #include "io/fichier.h"
00009
00010 #ifdef HAVE_BZLIB_H
00011 #include <bzlib.h>
00012 #endif //HAVE_BZLIB
00013
00014 const int buff_size=1024;
00015
00016 Fichier::Fichier()
00017 {
00018 nom_fichier=NULL;
00019 }
00020
00021 Fichier::~Fichier()
00022 {
00023 if(nom_fichier!=NULL)
00024 delete []nom_fichier;
00025 }
00026
00027 char* Fichier::GetLine()
00028 {
00029 int buff_size = 16;
00030 char* buff = (char*)malloc(buff_size);
00031 int i = 0;
00032 while(1)
00033 {
00034 buff[i] = GetChar();
00035 if(buff[i] == EOF || buff[i] == '\n')
00036 {
00037 buff[i] = '\0';
00038 return buff;
00039 }
00040 i++;
00041 if(i == buff_size)
00042 buff_size *= 2;
00043 buff = (char*)realloc(buff, buff_size);
00044 ASSERT(buff != NULL);
00045 }
00046 ASSERT(false);
00047 return NULL;
00048 }
00049
00050 FichierClassique::FichierClassique()
00051 {
00052 fichier=NULL;
00053 }
00054
00055 FichierClassique::~FichierClassique()
00056 {
00057 if(fichier!=NULL)
00058 Ferme();
00059 }
00060
00061 bool FichierClassique::Ouvre(const char* nom_fich, const char* att)
00062 {
00063 fichier=fopen(nom_fich,att);
00064 if(fichier==NULL)
00065 {
00066 log(LogWarning, "Cannot open file %s : %s", nom_fich, strerror(errno));
00067 return false;
00068 }
00069 nom_fichier=new char[strlen(nom_fich)+1];
00070 strcpy(nom_fichier,nom_fich);
00071 return true;
00072 }
00073
00074 void FichierClassique::Ferme()
00075 {
00076 fclose(fichier);
00077 fichier=NULL;
00078 }
00079
00080 char FichierClassique::GetChar()
00081 {
00082 last_char = fgetc(fichier);
00083 return last_char;
00084 }
00085
00086 void FichierClassique::UnGetChar()
00087 {
00088 ungetc(last_char, fichier);
00089 }
00090
00091 int FichierClassique::GetNbrLignes()
00092 {
00093 char car='\n';
00094 int nbr=0;
00095 while(1)
00096 {
00097 if(car=='\n')
00098 nbr++;
00099 car=fgetc(fichier);
00100 if(car==EOF)
00101 break;
00102 }
00103 rewind(fichier);
00104 return nbr;
00105 }
00106
00107 char* FichierClassique::GetExtension()
00108 {
00109 ASSERT(nom_fichier!=NULL);
00110 if(nom_fichier==NULL)
00111 return NULL;
00112 int i=strlen(nom_fichier)-1;
00113 while(i>0 && nom_fichier[i]!='.')
00114 i--;
00115
00116 if(i==0)
00117 return NULL;
00118
00119 char* ext=new char[strlen(&nom_fichier[i])+2];
00120 strcpy(ext,&nom_fichier[i]);
00121 return ext;
00122 }
00123
00124 #ifdef HAVE_BZLIB_H
00125 FichierBz2::FichierBz2()
00126 {
00127 fichier=NULL;
00128 buff=new char[buff_size];
00129 memset(buff, 1, buff_size);
00130 attribut=new char[10];
00131 }
00132
00133 FichierBz2::~FichierBz2()
00134 {
00135 if(fichier!=NULL)
00136 Ferme();
00137 delete []buff;
00138 delete []attribut;
00139 }
00140
00141 bool FichierBz2::Ouvre(const char* nom_fich, const char* att)
00142 {
00143 fichier=BZ2_bzopen(nom_fich,att);
00144 if(fichier==NULL)
00145 return false;
00146
00147 nom_fichier=new char[strlen(nom_fich)+1];
00148 strcpy(nom_fichier,nom_fich);
00149 strcpy(attribut,att);
00150 RemplitBuffer();
00151 offset=-1;
00152
00153 return true;
00154 }
00155
00156 void FichierBz2::Ferme()
00157 {
00158 BZ2_bzclose(fichier);
00159 fichier=NULL;
00160 }
00161
00162 void FichierBz2::RemplitBuffer()
00163 {
00164 int lu=1;
00165
00166
00167
00168 int i=0;
00169 while( i < buff_size )
00170 {
00171 if( buff[i] == EOF )
00172 break;
00173 break;
00174 }
00175 if(i == buff_size) i--;
00176 buff[0] = buff[i];
00177
00178
00179 offset=1;
00180 while(lu!=0 && offset!=buff_size)
00181 {
00182 unsigned char octet;
00183 lu=BZ2_bzread(fichier,&octet,1);
00184 buff[offset]=octet;
00185 offset++;
00186 }
00187 if(lu==0)
00188 buff[offset-1]=EOF;
00189 offset = 1;
00190 }
00191
00192 char FichierBz2::GetChar()
00193 {
00194 offset++;
00195 if(offset==buff_size)
00196 RemplitBuffer();
00197
00198 return buff[offset];
00199 }
00200
00201 void FichierBz2::UnGetChar()
00202 {
00203 offset--;
00204 ASSERT(offset >= 0);
00205 }
00206
00207 int FichierBz2::GetNbrLignes()
00208 {
00209 int car='\n';
00210 int nbr=0;
00211 do
00212 {
00213 if(car=='\n')
00214 nbr++;
00215 car=GetChar();
00216 }
00217 while(car!=EOF);
00218 Rewind();
00219 return nbr;
00220 }
00221
00222 void FichierBz2::Rewind()
00223 {
00224 Ferme();
00225 fichier=BZ2_bzopen(nom_fichier,attribut);
00226 RemplitBuffer();
00227 offset=-1;
00228 }
00229
00230 void FichierBz2::ErreurIci()
00231 {
00232 log(LogWarning,"Erreur de syntaxe dans le fichier \"%s\"",nom_fichier);
00233 }
00234
00235 char* FichierBz2::GetExtension()
00236 {
00237 ASSERT(nom_fichier!=NULL);
00238 if(nom_fichier==NULL)
00239 return NULL;
00240 int i=strlen(nom_fichier)-5;
00241 while(i>0 && nom_fichier[i]!='.')
00242 i--;
00243
00244 if(i==0)
00245 return NULL;
00246
00247 char* ext=new char[strlen(&nom_fichier[i])-2];
00248 strncpy(ext,&nom_fichier[i],strlen(&nom_fichier[i])-4);
00249 ext[strlen(&nom_fichier[i])-4]='\0';
00250 return ext;
00251 }
00252
00253 #endif //HAVE_BZLIB
00254
00255 Fichier* OuvreFichier(const char* nom_fich, const char* att)
00256 {
00257 Fichier* fich;
00258 if(nom_fich == NULL || strlen(nom_fich)==0)
00259 {
00260 log(LogWarning,"No name given to open file");
00261 return NULL;
00262 }
00263
00264 #ifdef HAVE_BZLIB_H
00265 if(strlen(nom_fich)>4 && strcmp(&nom_fich[strlen(nom_fich)-4],".bz2")==0)
00266 fich=new FichierBz2;
00267 else
00268 #endif
00269 fich=new FichierClassique;
00270 if(!fich->Ouvre(nom_fich,att))
00271 {
00272 delete fich;
00273 return NULL;
00274 }
00275 return fich;
00276 }
00277
00278 void FichierClassique::ErreurIci()
00279 {
00280 fpos_t pos_init;
00281 fgetpos(fichier,&pos_init);
00282
00283 long pos=ftell(fichier);
00284 long dec=15;
00285 if(pos<15)
00286 dec=pos;
00287 dec=-dec;
00288 if(fseek(fichier,dec,SEEK_CUR)==-1)
00289 {
00290 log(LogWarning,"tite erreur...");
00291 return;
00292 }
00293
00294 int aff=dec;
00295 char lu=fgetc(fichier);
00296 char ligne[4096];
00297 ligne[0] = '\0';
00298
00299 while (aff!=15 && lu!='\n' && lu!=EOF)
00300 {
00301 strncat(ligne, &lu, 1);
00302 aff++;
00303 lu=fgetc(fichier);
00304 }
00305 log(LogWarning,"%s", ligne);
00306
00307 ligne[0] = '\0';
00308 aff=dec+1;
00309 while (aff!=0)
00310 {
00311 strcat(ligne, " ");
00312 aff++;
00313 }
00314 strcat(ligne,"`--> ICI");
00315 log(LogWarning,"%s", ligne);
00316
00317 fsetpos(fichier,&pos_init);
00318 }
00319
00320 void erreur_ici(Fichier* fichier)
00321 {
00322 fichier->ErreurIci();
00323 }