00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #define __STDC_LIMIT_MACROS
00043 #include <stdint.h>
00044 #include <errno.h>
00045 #include <stdio.h>
00046 #include <libgen.h>
00047 #include <sys/stat.h>
00048 #include "anl_common.h"
00049 #include "anl_file_mngr.h"
00050
00051
00052
00053
00054 #undef int
00055
00056
00057
00058
00059
00060 const INT ANL_FILE_MNGR::_obuf_size;
00061
00062
00063
00064
00065
00066
00067 void
00068 ANL_FILE_MNGR::_Concat(char *buf,
00069 INT max_chars,
00070 const char *string[],
00071 INT num_strings)
00072 {
00073 INT char_cntr = 0;
00074
00075 for (INT i=0; i < num_strings; i++)
00076 {
00077 const char *s = string[i];
00078
00079 for (INT j=0; char_cntr < max_chars && s[j] != '\0'; j++)
00080 buf[char_cntr++] = s[j];
00081 }
00082 if (char_cntr < max_chars)
00083 buf[char_cntr] = '\0';
00084 else
00085 buf[max_chars-1] = '\0';
00086 }
00087
00088
00089 UINT64
00090 ANL_FILE_MNGR::_Get_Decimal_Number(INT ch)
00091 {
00092
00093
00094 switch (ch)
00095 {
00096 case '0':
00097 return 0;
00098 case '1':
00099 return 1;
00100 case '2':
00101 return 2;
00102 case '3':
00103 return 3;
00104 case '4':
00105 return 4;
00106 case '5':
00107 return 5;
00108 case '6':
00109 return 6;
00110 case '7':
00111 return 7;
00112 case '8':
00113 return 8;
00114 case '9':
00115 return 9;
00116 default:
00117 return UINT64_MAX;
00118 }
00119 }
00120
00121
00122 UINT64
00123 ANL_FILE_MNGR::_Get_Hex_Number(INT ch)
00124 {
00125
00126
00127 switch (ch)
00128 {
00129 case 'a':
00130 return 10;
00131 case 'b':
00132 return 11;
00133 case 'c':
00134 return 12;
00135 case 'd':
00136 return 13;
00137 case 'e':
00138 return 14;
00139 case 'f':
00140 return 15;
00141 case 'A':
00142 return 10;
00143 case 'B':
00144 return 11;
00145 case 'C':
00146 return 12;
00147 case 'D':
00148 return 13;
00149 case 'E':
00150 return 14;
00151 case 'F':
00152 return 15;
00153 case '0':
00154 return 0;
00155 case '1':
00156 return 1;
00157 case '2':
00158 return 2;
00159 case '3':
00160 return 3;
00161 case '4':
00162 return 4;
00163 case '5':
00164 return 5;
00165 case '6':
00166 return 6;
00167 case '7':
00168 return 7;
00169 case '8':
00170 return 8;
00171 case '9':
00172 return 9;
00173 default:
00174 return UINT64_MAX;
00175 }
00176 }
00177
00178
00179 BOOL
00180 ANL_FILE_MNGR::_Exists(const char *name)
00181 {
00182 INT st;
00183 struct stat sbuf;
00184 st = stat(name, &sbuf);
00185 if (st == -1 && (errno == ENOENT || errno == ENOTDIR))
00186 return FALSE;
00187 else
00188 return TRUE;
00189 }
00190
00191
00192 void
00193 ANL_FILE_MNGR::_General_Check(BOOL c, const char *proc_name, const char *msg)
00194 {
00195 if (!c)
00196 {
00197 char strbuf[500];
00198 const char *strlist[5] = {proc_name, msg, " (", _name, ")"};
00199 _Concat(strbuf, 500, strlist, 5);
00200 _diag->Warning(strbuf);
00201 }
00202 }
00203
00204
00205 void
00206 ANL_FILE_MNGR::_Not_Open_Check(const char *proc_name, const char *to_be_opened)
00207 {
00208 if (File_Is_Open())
00209 {
00210 char strbuf[500];
00211 const char *strlist[5] = {proc_name,
00212 " will close unexpected open file ",
00213 _name,
00214 " and then open. ",
00215 to_be_opened};
00216 _Concat(strbuf, 500, strlist, 5);
00217 _diag->Warning(strbuf);
00218 Close_File();
00219 }
00220 }
00221
00222
00223 void
00224 ANL_FILE_MNGR::_Is_Open_Check(const char *proc_name)
00225 {
00226 if (!File_Is_Open())
00227 {
00228 char strbuf[500];
00229 const char *strlist[2] = {proc_name,
00230 " expected a file to have been opened"};
00231 _Concat(strbuf, 500, strlist, 2);
00232 _diag->Error(strbuf);
00233 }
00234 }
00235
00236
00237 void
00238 ANL_FILE_MNGR::_Overwrite_Warning(const char *proc_name, const char *filename)
00239 {
00240 if (_Exists(filename))
00241 {
00242 char strbuf[500];
00243 const char *strlist[4] = {filename,
00244 " will be overwritten (by ",
00245 proc_name,
00246 ")"};
00247 _Concat(strbuf, 500, strlist, 4);
00248 _diag->Warning(strbuf);
00249 }
00250 }
00251
00252
00253 void ANL_FILE_MNGR::_Write_Obuf()
00254 {
00255 INT status;
00256
00257 _obuf[_next_obuf] = '\0';
00258 status = fputs(_obuf, _file);
00259 _next_obuf = 0;
00260 _General_Check(status != EOF,
00261 "ANL_FILE_MNGR::_Write_Obuf",
00262 "cannot write to file");
00263 }
00264
00265
00266
00267
00268
00269 void
00270 ANL_FILE_MNGR::Open_Read(const char *name)
00271 {
00272 _Not_Open_Check("ANL_FILE_MNGR::Open_Read", name);
00273 _file = fopen(name, "r");
00274 _Is_Open_Check("ANL_FILE_MNGR::Open_Read");
00275 _name = name;
00276 _next_ch = getc(_file);
00277 _General_Check(!ferror(_file),
00278 "ANL_FILE_MNGR::Open_Read",
00279 "cannot read first character in file");
00280 }
00281
00282
00283 void
00284 ANL_FILE_MNGR::Open_Create(const char *name)
00285 {
00286 _Not_Open_Check("ANL_FILE_MNGR::Open_Create", name);
00287 _Overwrite_Warning("ANL_FILE_MNGR::Open_Create", name);
00288 _file = fopen(name, "w");
00289 _Is_Open_Check("ANL_FILE_MNGR::Open_Create");
00290 _name = name;
00291 }
00292
00293
00294 void
00295 ANL_FILE_MNGR::Open_Append(const char *name)
00296 {
00297 _Not_Open_Check("ANL_FILE_MNGR::Open_Append", name);
00298 _file = fopen(name, "a");
00299 _Is_Open_Check("ANL_FILE_MNGR::Open_Append");
00300 _name = name;
00301 }
00302
00303
00304 void
00305 ANL_FILE_MNGR::Close_File()
00306 {
00307 INT32 status;
00308
00309 if (_next_obuf > 0)
00310 _Write_Obuf();
00311 status = fclose(_file);
00312 _General_Check(status == 0,
00313 "ANL_FILE_MNGR::Close_File",
00314 "cannot close file");
00315 _file = NULL;
00316 _name = NULL;
00317 }
00318
00319
00320 void
00321 ANL_FILE_MNGR::Close_And_Remove_File()
00322 {
00323 INT32 status;
00324
00325 if (_next_obuf > 0)
00326 _Write_Obuf();
00327 status = fclose(_file);
00328 _General_Check(status == 0,
00329 "ANL_FILE_MNGR::Close_File",
00330 "cannot close file");
00331 remove(_name);
00332 _file = NULL;
00333 _name = NULL;
00334 }
00335
00336
00337 char
00338 ANL_FILE_MNGR::Read_Char()
00339 {
00340 INT32 ch;
00341
00342 _General_Check(!End_Of_File(),
00343 "ANL_FILE_MNGR::Read_Char",
00344 "attempt to read beyond the end of the file");
00345 ch = _next_ch;
00346 _next_ch = getc(_file);
00347 return ch;
00348 }
00349
00350
00351 UINT64
00352 ANL_FILE_MNGR::Read_Uint64(BOOL as_hex)
00353 {
00354 INT32 num_digits = 0;
00355 UINT64 result = 0;
00356 UINT64 digit;
00357
00358 _General_Check(!End_Of_File(),
00359 "ANL_FILE_MNGR::Read_Uint64",
00360 "attempt to read beyond the end of the file");
00361 if (as_hex)
00362 {
00363 if (_next_ch == '0')
00364 {
00365 _next_ch = getc(_file);
00366 if (_next_ch == 'x' || _next_ch == 'X')
00367 _next_ch = getc(_file);
00368 else
00369 num_digits++;
00370 }
00371
00372 for (digit = _Get_Hex_Number(_next_ch);
00373 digit != UINT64_MAX;
00374 digit = _Get_Hex_Number(_next_ch))
00375 {
00376 _next_ch = getc(_file);
00377 result = result*16 + digit;
00378 num_digits++;
00379 }
00380 _General_Check(num_digits > 0 && num_digits <= 17,
00381 "ANL_FILE_MNGR::Read_Uint64",
00382 "unexpected syntax");
00383 }
00384 else
00385 {
00386 for (digit = _Get_Decimal_Number(_next_ch);
00387 digit != UINT64_MAX;
00388 digit = _Get_Decimal_Number(_next_ch))
00389 {
00390 _next_ch = getc(_file);
00391 result = result*10 + digit;
00392 num_digits++;
00393 }
00394 _General_Check(num_digits > 0 && num_digits <= 17,
00395 "ANL_FILE_MNGR::Read_Uint64",
00396 "unexpected syntax");
00397 }
00398
00399 return result;
00400 }
00401
00402
00403 void
00404 ANL_FILE_MNGR::Write_Char(char c)
00405 {
00406 if (_next_obuf >= _obuf_size)
00407 _Write_Obuf();
00408
00409 _obuf[_next_obuf++] = c;
00410 }
00411
00412
00413 void
00414 ANL_FILE_MNGR::Write_String(const char *s)
00415 {
00416 if (s != NULL)
00417 for (const char *p = s; *p != '\0'; p++)
00418 {
00419 if (_next_obuf >= _obuf_size)
00420 _Write_Obuf();
00421 _obuf[_next_obuf++] = *p;
00422 }
00423 }