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