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