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