ADMB Documentation  11.5.3152
 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 
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   else
00097   {
00098     line = 0;
00099     field = 0;
00100     ignore_eof = 0;
00101   }
00102   memset(comment_line, '\0', SIGNATURE_LENGTH);
00103   memset(signature_line, '\0', SIGNATURE_LENGTH);
00104 }
00105 
00106 void cifstream::filter(void)
00107 {
00108   //char testc = bp->NEXTCHAR();
00109   int testc = bp->sgetc();
00110  // cout << "in filter testc= " << testc << endl;
00111   while (isspace(testc))
00112   {
00113     testc = bp->snextc();
00114  //   cout << "in filter testc= " << testc << endl;
00115   }
00116 
00117   while ( (good()) && (testc == COMMENT_CHAR) && (testc != EOF))
00118   {
00119     int n = 0;
00120     // skip characters until newline
00121     do
00122     {
00123       if (n < SIGNATURE_LENGTH)
00124         comment_line[n++] = (char)testc;
00125 
00126       testc = bp->snextc();
00127       //cout << "in filter testc= " << testc << endl;
00128       if (testc == '\n')
00129       {
00130         comment_line[n++] = '\0';
00131         if (line == 1)
00132           strcpy(signature_line, comment_line);
00133         line ++;
00134         field = 0;
00135       }
00136     } while (testc != '\n');
00137 
00138     // get first character in next line
00139     testc = bp->snextc();
00140 
00141     while (testc == ' ' || testc == '\n' || testc == '\r')
00142       testc = bp->snextc();
00143   }
00144   if ( (!good()) || (testc == EOF))
00145   {
00146     if (testc == EOF)
00147       set_eof_bit();
00148     report_error(
00149       "function: void cifstream::prefilter(); premature end of file?");
00150   }
00151 }
00152 
00153 void cifstream::get_field(char* s,int space_flag)
00154 {
00155   filter();
00156 
00157   // remove leading blanks
00158   int testc = bp->sgetc();
00159   while (isspace(testc))
00160   {
00161     testc = bp->snextc();
00162   }
00163 
00164   int n = 0;
00165   if (!space_flag)
00166   {
00167     while ( (n < FILTER_BUF_SIZE) && !isspace(testc) && (testc != EOF))
00168     {
00169       s[n++] = (char)testc;
00170       testc = bp->snextc();
00171     }
00172   }
00173   else
00174   {
00175     while ( (n < FILTER_BUF_SIZE) && (testc != EOF))
00176     {
00177       s[n++] = (char)testc;
00178       testc = bp->snextc();
00179     }
00180   }
00181   if (n>=FILTER_BUF_SIZE)
00182   {
00183     report_error("function: void cifstream::prefilter();"
00184         " Buffer size exceeded?");
00185   }
00186 
00187   if ( (!good()) || (testc == EOF))
00188   {
00189     if (testc == EOF)
00190       set_eof_bit();
00191     report_error(
00192       "function: void cifstream::prefilter(); premature end of file?");
00193   }
00194   s[n++] = '\0';
00195   field ++;
00196 }
00197 
00198 cifstream& cifstream::operator >> (adstring& s)
00199 {
00200   char * t = new char[FILTER_BUF_SIZE];
00201   (*this) >> t;
00202   s.realloc(t);
00203   delete [] t;
00204   return (*this);
00205 }
00206 
00207 // the new version
00208 cifstream& cifstream::operator>>(const adstring& _s)
00209 {
00210   adstring& s = (adstring&) _s;
00211   char * t = new char[FILTER_BUF_SIZE];
00212   (*this) >> t;
00213   s.realloc(t);
00214   delete [] t;
00215   return (*this);
00216 }
00217 
00218 cifstream& cifstream::operator>>(const line_adstring& s)
00219 {
00220   get_field((char*)(const char *)(s),1);
00221   return (*this);
00222 }
00223 
00224 
00225 cifstream& cifstream::operator >> (char* c)
00226 {
00227   get_field((char*)c);
00228   return *this;
00229 }
00230 
00231 cifstream& cifstream::operator>>(const char* c)
00232 {
00233   get_field((char*)c);
00234   return *this;
00235 }
00236 
00237 cifstream& cifstream::operator>>(const long& i)
00238 {
00239   char * s = new char[FILTER_BUF_SIZE];
00240   get_field(s);
00241   istringstream is(s);
00242   is >> (long&) i;
00243 #ifdef __NDPX__
00244   if (is.eof()) is.clear();
00245 #endif
00246   if (!is)
00247   {
00248     this->clear(is.rdstate());
00249     report_error("lont int extraction operator");
00250   }
00251   delete []s;
00252   return *this;
00253 }
00254 
00255 #if defined(__ADSGI__)
00256 istream& istream::operator>>(long long & x)
00257 {
00258   long int i;
00259   (*this) >> i;
00260   x=i;
00261   return *this;
00262 }
00263 #else
00264 cifstream& cifstream::operator>>(long long & i)
00265 {
00266   char * s = new char[FILTER_BUF_SIZE];
00267   get_field(s);
00268   istringstream is(s);
00269   is >> i;
00270 #ifdef __NDPX__
00271   if (is.eof()) is.clear();
00272 #endif
00273   if (!is)
00274   {
00275     this->clear(is.rdstate());
00276     report_error("lont int extraction operator");
00277   }
00278   delete []s;
00279   return *this;
00280 }
00281 #endif
00282 
00283 void js_strip_leading_zeros(char * s)
00284 {
00285   size_t n = strlen(s) - 1;
00286   size_t i = 0;
00287 
00288   while ((i < n) && (s[i]=='0') )
00289   {
00290      s[i] = ' ';
00291      i++;
00292   }
00293 }
00294 
00295 cifstream& cifstream::operator>>(const int& i)
00296 {
00297   char * s = new char[FILTER_BUF_SIZE];
00298   get_field(s);
00299   //cout << "cifstream& cifstream::operator >> (int& i) s = '" << s
00300   //     << "'" << endl;
00301   js_strip_leading_zeros(s);
00302   istringstream is(s);
00303   is >> (int&)i;
00304 #ifdef __NDPX__
00305   if (is.eof()) is.clear();
00306 #endif
00307   if (!is)
00308   {
00309     this->clear(is.rdstate());
00310     report_error("int extraction operator");
00311   }
00312   delete []s;
00313   return *this;
00314 }
00315 
00316 cifstream& cifstream::operator>>(const double& _x)
00317 {
00318   double& x = (double&)(_x);
00319   //char * s = new char[FILTER_BUF_SIZE];
00320   char* s = (char*)malloc(8000*sizeof(char));
00321   if (s)
00322   {
00323     get_field(s);
00324     if (s[0]=='#' && s[1] == '\0')
00325       get_field(s);
00326 
00327 #if !defined(__BORLANDC__)
00328     istringstream is(s);
00329     if (!is)
00330     {
00331       this->clear(is.rdstate());
00332       report_error("double extraction operator");
00333     }
00334     is >> x;
00335 
00336   #ifdef __NDPX__
00337     if (is.eof()) is.clear();
00338   #endif
00339     if (!is)
00340     {
00341       this->clear(is.rdstate());
00342       report_error("double extraction operator");
00343     }
00344 #else
00345     char* end=0;
00346     x=strtod(s,&end);
00347 #endif
00348 
00349     //delete [] s;
00350     free(s);
00351     s = 0;
00352   }
00353   return *this;
00354 }
00355 
00356 cifstream& cifstream::operator>>(const float& x)
00357 {
00358   char * s = new char[FILTER_BUF_SIZE];
00359   get_field(s);
00360   istringstream is(s);
00361   is >> (float&)x;
00362 #ifdef __NDPX__
00363   if (is.eof()) is.clear();
00364 #endif
00365   if (!is)
00366   {
00367     this->clear(is.rdstate());
00368     report_error("float extraction operator");
00369   }
00370   delete []s;
00371   return *this;
00372 }
00373 
00377 cifstream& cifstream::getline(char* s, int k, char d)
00378 {
00379   filter();
00380 
00381   s[0] = '\0';
00382   int n = 0;
00383   int testc = bp->sbumpc();
00384   while ( (!eof()) && (n < k) && (testc != d) && (testc != EOF))
00385   {
00386     s[n++] = (char)testc;
00387     testc = bp->sbumpc();
00388   }
00389   s[n++] = '\0';
00390 
00391   return *this;
00392 }
00393 
00394 /*
00395 void cifstream::report_error(const char * msg)
00396 {
00397   int ss  = rdstate();
00398   //cout << "stream state = " << ss << endl;
00399 #ifdef __BCPLUSPLUS___
00400   int end = eof();
00401 #endif
00402 #ifdef __ZTC__
00403   int end = (ss < 4);
00404 #endif
00405   //cout << "eof() = " << end << endl;
00406   //cout << "ignore_eof = " << ignore_eof << endl;
00407 
00408   if (!end || (end && ignore_eof))
00409   {
00410     cerr << "\n** error reading file '" << file_name
00411          << "' at line " << line
00412          << ", field " << field
00413          << endl;
00414     if (msg)
00415       cerr << "   " << msg << endl;
00416     if (end)
00417       cerr << "   end of file" << endl;
00418     //exit(1);
00419   }
00420 }
00421 */
00422 
00423 void cifstream::report_error(const char * msg) {;}
00424 
00425 /*
00426 #if !defined(__ADSGI__)
00427   void strnset(char * comment_line, char x, size_t len)
00428 #else
00429   void strnset(char * comment_line, const char x, size_t len)
00430 #endif
00431   {
00432     unsigned int tlen;
00433     //len=100;
00434     //tlen=strlen(comment_line);
00435     tlen=strlen("x");
00436     if (tlen>len)tlen=len;
00437     memset(comment_line,x,tlen);
00438   }
00439 */