ADMB Documentation  11.1x.2738
 All Classes Files Functions Variables Typedefs Friends Defines
cifstrem.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: cifstrem.cpp 2708 2014-11-21 20:09:19Z johnoel $
00003  *
00004  * Author: David Fournier
00005  * Copyright (c) 2008-2012 Regents of the University of California
00006  */
00011 #include <sstream>
00012 using std::istringstream;
00013 
00014 #include <fvar.hpp>
00015 
00016 #if defined(__GNUC__) && (__GNUC__ < 3)
00017   #pragma implementation "cifstrem.h"
00018 #endif
00019 
00020 #include "cifstrem.h"
00021 
00022 void cifstream::set_eof_bit(void)
00023 {
00024 #ifdef __BCPLUSPLUS__
00025   int current_state = rdstate();
00026   setstate(current_state | ios::eofbit);
00027 #endif
00028 #ifdef __ZTC__
00029   int current_state = rdstate();
00030   clear(current_state | ios::eofbit);
00031 #endif
00032 }
00033 
00037 char* cifstream::signature()
00038 {
00039   if (strlen(signature_line) <= 0)
00040   {
00041     int c = bp->sgetc();
00042 
00043     int n = 0;
00044     while ((n < SIGNATURE_LENGTH) && (c != '\n'))
00045     {
00046       signature_line[n++] = (char)c;
00047       c = bp->snextc();
00048     }
00049     signature_line[n++] = '\0';
00050     strcpy(comment_line, signature_line);
00051 
00052     // read until end of line incase line is longer than SIGNATURE_LENGTH
00053     while (c != '\n')
00054     {
00055       c = bp->snextc();
00056     }
00057 
00058     // just position buffer to first character of next line
00059     bp->snextc();
00060 
00061     line++;
00062   }
00063   return signature_line;
00064 }
00065 
00066 adstring cifstream::get_file_name(void)
00067 {
00068   return file_name;
00069 }
00070 
00071 cifstream::cifstream(const char* fn, int open_m, char cc)
00072 #if defined (_MSC_VER) || defined (__WAT32__)
00073  : ifstream(fn, ios::in | open_m) , file_name(fn)
00074 #elif defined(__BCPLUSPLUS__)
00075  : ifstream(fn, ios::in | open_m) , file_name(fn)
00076 #elif defined (__NDPX__)
00077  : ifstream(fn, ios::in | open_m) , file_name(fn)
00078 #elif defined (__INTEL_COMPILER)
00079  : ifstream(fn) , file_name(fn)
00080 #elif defined(__SUNPRO_CC)
00081  : ifstream(fn, ios::in | open_m) , file_name(fn)
00082 #elif defined (__ZTC__)
00083  : ios(&buffer), ifstream(fn, ios::in | open_m) , file_name(fn)
00084 #else
00085  : ifstream(fn, ios::in | std::ios::openmode(open_m)) , file_name(fn)
00086 #endif
00087 {
00088   bp = rdbuf();
00089   COMMENT_CHAR = cc;
00090   if (this->good())
00091   {
00092     line = 1;
00093     field = 0;
00094     ignore_eof = 1;
00095   }
00096   memset(comment_line, '\0', SIGNATURE_LENGTH);
00097   memset(signature_line, '\0', SIGNATURE_LENGTH);
00098 }
00099 
00100 void cifstream::filter(void)
00101 {
00102   //char testc = bp->NEXTCHAR();
00103   int testc = bp->sgetc();
00104  // cout << "in filter testc= " << testc << endl;
00105   while (isspace(testc))
00106   {
00107     testc = bp->snextc();
00108  //   cout << "in filter testc= " << testc << endl;
00109   }
00110 
00111   while ( (good()) && (testc == COMMENT_CHAR) && (testc != EOF))
00112   {
00113     int n = 0;
00114     // skip characters until newline
00115     do
00116     {
00117       if (n < SIGNATURE_LENGTH)
00118         comment_line[n++] = (char)testc;
00119 
00120       testc = bp->snextc();
00121       //cout << "in filter testc= " << testc << endl;
00122       if (testc == '\n')
00123       {
00124         comment_line[n++] = '\0';
00125         if (line == 1)
00126           strcpy(signature_line, comment_line);
00127         line ++;
00128         field = 0;
00129       }
00130     } while (testc != '\n');
00131 
00132     // get first character in next line
00133     testc = bp->snextc();
00134 
00135     while (testc == ' ' || testc == '\n' || testc == '\r')
00136       testc = bp->snextc();
00137   }
00138   if ( (!good()) || (testc == EOF))
00139   {
00140     if (testc == EOF)
00141       set_eof_bit();
00142     report_error(
00143       "function: void cifstream::prefilter(); premature end of file?");
00144   }
00145 }
00146 
00147 void cifstream::get_field(char* s,int space_flag)
00148 {
00149   filter();
00150 
00151   // remove leading blanks
00152   int testc = bp->sgetc();
00153   while (isspace(testc))
00154   {
00155     testc = bp->snextc();
00156   }
00157 
00158   int n = 0;
00159   if (!space_flag)
00160   {
00161     while ( (n < FILTER_BUF_SIZE) && !isspace(testc) && (testc != EOF))
00162     {
00163       s[n++] = (char)testc;
00164       testc = bp->snextc();
00165     }
00166   }
00167   else
00168   {
00169     while ( (n < FILTER_BUF_SIZE) && (testc != EOF))
00170     {
00171       s[n++] = (char)testc;
00172       testc = bp->snextc();
00173     }
00174   }
00175   if (n>=FILTER_BUF_SIZE)
00176   {
00177     report_error("function: void cifstream::prefilter();"
00178         " Buffer size exceeded?");
00179   }
00180 
00181   if ( (!good()) || (testc == EOF))
00182   {
00183     if (testc == EOF)
00184       set_eof_bit();
00185     report_error(
00186       "function: void cifstream::prefilter(); premature end of file?");
00187   }
00188   s[n++] = '\0';
00189   field ++;
00190 }
00191 
00192 cifstream& cifstream::operator >> (adstring& s)
00193 {
00194   char * t = new char[FILTER_BUF_SIZE];
00195   (*this) >> t;
00196   s.realloc(t);
00197   delete [] t;
00198   return (*this);
00199 }
00200 
00201 // the new version
00202 cifstream& cifstream::operator>>(const adstring& _s)
00203 {
00204   adstring& s = (adstring&) _s;
00205   char * t = new char[FILTER_BUF_SIZE];
00206   (*this) >> t;
00207   s.realloc(t);
00208   delete [] t;
00209   return (*this);
00210 }
00211 
00212 cifstream& cifstream::operator>>(const line_adstring& s)
00213 {
00214   get_field((char*)(const char *)(s),1);
00215   return (*this);
00216 }
00217 
00218 
00219 cifstream& cifstream::operator >> (char* c)
00220 {
00221   get_field((char*)c);
00222   return *this;
00223 }
00224 
00225 cifstream& cifstream::operator>>(const char* c)
00226 {
00227   get_field((char*)c);
00228   return *this;
00229 }
00230 
00231 cifstream& cifstream::operator>>(const long& i)
00232 {
00233   char * s = new char[FILTER_BUF_SIZE];
00234   get_field(s);
00235   istringstream is(s);
00236   is >> (long&) i;
00237 #ifdef __NDPX__
00238   if (is.eof()) is.clear();
00239 #endif
00240   if (!is)
00241   {
00242     this->clear(is.rdstate());
00243     report_error("lont int extraction operator");
00244   }
00245   delete []s;
00246   return *this;
00247 }
00248 
00249 #if defined(__ADSGI__)
00250 istream& istream::operator>>(long long & x)
00251 {
00252   long int i;
00253   (*this) >> i;
00254   x=i;
00255   return *this;
00256 }
00257 #else
00258 cifstream& cifstream::operator>>(long long & i)
00259 {
00260   char * s = new char[FILTER_BUF_SIZE];
00261   get_field(s);
00262   istringstream is(s);
00263   is >> i;
00264 #ifdef __NDPX__
00265   if (is.eof()) is.clear();
00266 #endif
00267   if (!is)
00268   {
00269     this->clear(is.rdstate());
00270     report_error("lont int extraction operator");
00271   }
00272   delete []s;
00273   return *this;
00274 }
00275 #endif
00276 
00277 void js_strip_leading_zeros(char * s)
00278 {
00279   size_t n = strlen(s) - 1;
00280   size_t i = 0;
00281 
00282   while ((i < n) && (s[i]=='0') )
00283   {
00284      s[i] = ' ';
00285      i++;
00286   }
00287 }
00288 
00289 cifstream& cifstream::operator>>(const int& i)
00290 {
00291   char * s = new char[FILTER_BUF_SIZE];
00292   get_field(s);
00293   //cout << "cifstream& cifstream::operator >> (int& i) s = '" << s
00294   //     << "'" << endl;
00295   js_strip_leading_zeros(s);
00296   istringstream is(s);
00297   is >> (int&)i;
00298 #ifdef __NDPX__
00299   if (is.eof()) is.clear();
00300 #endif
00301   if (!is)
00302   {
00303     this->clear(is.rdstate());
00304     report_error("int extraction operator");
00305   }
00306   delete []s;
00307   return *this;
00308 }
00309 
00310 cifstream& cifstream::operator>>(const double& _x)
00311 {
00312   double& x = (double&)(_x);
00313   //char * s = new char[FILTER_BUF_SIZE];
00314   char* s = (char*)malloc(8000*sizeof(char));
00315   if (s)
00316   {
00317     get_field(s);
00318     if (s[0]=='#' && s[1] == '\0')
00319       get_field(s);
00320 
00321 #if !defined(__BORLANDC__)
00322     istringstream is(s);
00323     if (!is)
00324     {
00325       this->clear(is.rdstate());
00326       report_error("double extraction operator");
00327     }
00328     is >> x;
00329 
00330   #ifdef __NDPX__
00331     if (is.eof()) is.clear();
00332   #endif
00333     if (!is)
00334     {
00335       this->clear(is.rdstate());
00336       report_error("double extraction operator");
00337     }
00338 #else
00339     char* end=0;
00340     x=strtod(s,&end);
00341 #endif
00342 
00343     //delete [] s;
00344     free(s);
00345     s = 0;
00346   }
00347   return *this;
00348 }
00349 
00350 cifstream& cifstream::operator>>(const float& x)
00351 {
00352   char * s = new char[FILTER_BUF_SIZE];
00353   get_field(s);
00354   istringstream is(s);
00355   is >> (float&)x;
00356 #ifdef __NDPX__
00357   if (is.eof()) is.clear();
00358 #endif
00359   if (!is)
00360   {
00361     this->clear(is.rdstate());
00362     report_error("float extraction operator");
00363   }
00364   delete []s;
00365   return *this;
00366 }
00367 
00371 cifstream& cifstream::getline(char* s, int k, char d)
00372 {
00373   filter();
00374 
00375   s[0] = '\0';
00376   int n = 0;
00377   int testc = bp->sbumpc();
00378   while ( (!eof()) && (n < k) && (testc != d) && (testc != EOF))
00379   {
00380     s[n++] = (char)testc;
00381     testc = bp->sbumpc();
00382   }
00383   s[n++] = '\0';
00384 
00385   return *this;
00386 }
00387 
00388 /*
00389 void cifstream::report_error(const char * msg)
00390 {
00391   int ss  = rdstate();
00392   //cout << "stream state = " << ss << endl;
00393 #ifdef __BCPLUSPLUS___
00394   int end = eof();
00395 #endif
00396 #ifdef __ZTC__
00397   int end = (ss < 4);
00398 #endif
00399   //cout << "eof() = " << end << endl;
00400   //cout << "ignore_eof = " << ignore_eof << endl;
00401 
00402   if (!end || (end && ignore_eof))
00403   {
00404     cerr << "\n** error reading file '" << file_name
00405          << "' at line " << line
00406          << ", field " << field
00407          << endl;
00408     if (msg)
00409       cerr << "   " << msg << endl;
00410     if (end)
00411       cerr << "   end of file" << endl;
00412     //exit(1);
00413   }
00414 }
00415 */
00416 
00417 void cifstream::report_error(const char * msg) {;}
00418 
00419 /*
00420 #if !defined(__ADSGI__)
00421   void strnset(char * comment_line, char x, size_t len)
00422 #else
00423   void strnset(char * comment_line, const char x, size_t len)
00424 #endif
00425   {
00426     unsigned int tlen;
00427     //len=100;
00428     //tlen=strlen(comment_line);
00429     tlen=strlen("x");
00430     if (tlen>len)tlen=len;
00431     memset(comment_line,x,tlen);
00432   }
00433 */