ADMB Documentation  11.1x.2723
 All Classes Files Functions Variables Typedefs Friends Defines
df1b2f10.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: df1b2f10.cpp 2719 2014-11-25 00:14:20Z johnoel $
00003  *
00004  * Author: David Fournier
00005  * Copyright (c) 2008-2012 Regents of the University of California
00006  */
00011 #include <df1b2fun.h>
00012 
00013 #ifdef OPT_LIB
00014   #define NDEBUG
00015 #endif
00016 #include <cassert>
00017 
00018 #ifdef _MSC_VER
00019   #ifdef _M_X64
00020   typedef __int64 ssize_t;
00021   #else
00022   typedef int ssize_t;
00023   #endif
00024 #else
00025   #include <unistd.h>
00026 #endif
00027 
00032 void test_smartlist::reset(void)
00033 {
00034   bptr=buffer;
00035   eof_flag=0;
00036   lseek(fp, 0L, SEEK_SET);
00037   written_flag=0;
00038   end_saved=0;
00039 }
00040 
00044 test_smartlist::test_smartlist(void)
00045 {
00046   bufsize=0;
00047   buffer=0;
00048   true_buffer=0;
00049   buffend=0;
00050   bptr=0;
00051   fp=-1;
00052 }
00053 
00058 test_smartlist::test_smartlist(const size_t _bufsize,const adstring& _filename)
00059 {
00060   allocate(_bufsize,_filename);
00061 }
00062 
00067 void test_smartlist::allocate(const size_t _bufsize,const adstring& _filename)
00068 {
00069   //cerr << "need to modify test_smartlist class for multibyte char" << endl;
00070   assert(sizeof(char) == 1);
00071 
00072   end_saved=0;
00073   eof_flag=0;
00074   noreadflag=0;
00075   written_flag=0;
00076   direction=0;
00077   bufsize=_bufsize;
00078   filename=_filename;
00079   //AD_ALLOCATE(true_buffer,char,bufsize+2*sizeof(double),df1b2_gradlist)
00080   if ((true_buffer=new char[(bufsize+2)*sizeof(double) ])==0)
00081   {
00082     cerr << "Allocation error in df1b2_gradlist" << endl;
00083     ad_exit(1);
00084   }
00085   doubleptr=(double*)true_buffer;
00086   true_buffend=true_buffer+bufsize+2*sizeof(double)-1;
00087   buffer=true_buffer+sizeof(double);
00088   *(double*)(true_buffer)=5678.9;
00089   *(double*)(true_buffer+bufsize+sizeof(double))=9876.5;
00090   //buffend=true_buffer+bufsize-1+sizeof(double);
00091   buffend=true_buffer+bufsize-1;
00092   bptr=buffer;
00093   fp=open((char*)(filename), O_RDWR | O_CREAT | O_TRUNC |
00094                    O_BINARY, S_IREAD | S_IWRITE);
00095   if (fp == -1)
00096   {
00097     cerr << "Error trying to open file " << filename
00098          << " in class test_smartlist " << endl;
00099     exit(1);
00100   }
00101 
00102   /*off_t pos=*/lseek(fp,0L,SEEK_CUR);
00103 }
00104 
00109 void test_smartlist::write(const size_t n)
00110 {
00111 #ifdef __MINGW64__
00112   #ifndef OPT_LIB
00113   assert(n <= UINT_MAX);
00114   #endif
00115   ssize_t nw = ::write(fp,buffer,(unsigned int)n);
00116 #else
00117   ssize_t nw = ::write(fp,buffer,n);
00118 #endif
00119   if (nw <= -1 || n != (size_t)nw)
00120   {
00121     cerr << "Error writing to file " << filename << endl;
00122     ad_exit(1);
00123   }
00124 }
00125 
00130 void test_smartlist::rewind(void)
00131 {
00132   bptr=buffer;
00133   if (written_flag)
00134   {
00135     lseek(fp,0L,SEEK_SET);
00136     // get the record size
00137     unsigned int nbytes = 0;
00138 #ifdef OPT_LIB
00139     ::read(fp,&nbytes,sizeof(unsigned int));
00140 #else
00141     ssize_t ret = ::read(fp,&nbytes,sizeof(unsigned int));
00142     assert(ret != -1);
00143 #endif
00144     if (nbytes > bufsize)
00145     {
00146       cerr << "Error -- record size in file seems to be larger than"
00147        " the buffer it was created from " << endl
00148         << " buffer size is " << bufsize << " record size is supposedly "
00149         << nbytes << endl;
00150     }
00151 #ifdef OPT_LIB
00152     ::read(fp,buffer,nbytes);
00153 #else
00154     // now read the record into the buffer
00155     ret = ::read(fp,buffer,nbytes);
00156     assert(ret != -1);
00157 #endif
00158     //cout << "Number of bytes read " << nr << endl;
00159     // skip over file postion entry in file
00160     // so we are ready to read second record
00161     lseek(fp, (off_t)sizeof(off_t), SEEK_CUR);
00162   }
00163 }
00164 
00169 void test_smartlist::initialize(void)
00170 {
00171   end_saved=0;
00172   bptr=buffer;
00173   //int nbytes=0;
00174   written_flag=0;
00175   lseek(fp,0L,SEEK_SET);
00176   set_forward();
00177 }
00178 
00183 void test_smartlist::check_buffer_size(const size_t nsize)
00184 {
00185   if ( bptr+nsize-1 > buffend)
00186   {
00187     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00188     {
00189       read_buffer();
00190     }
00191     else
00192     {
00193       if (nsize>bufsize)
00194       {
00195          cout << "Need to increase buffsize in list" << endl;
00196          exit(1);
00197       }
00198       write_buffer();
00199     }
00200   }
00201 }
00202 
00207 void test_smartlist::restore_end(void)
00208 {
00209   if (written_flag)
00210   {
00211     if (end_saved)
00212     {
00213       read_buffer();
00214       set_recend();
00215     }
00216   }
00217 }
00218 
00223 void test_smartlist::save_end(void)
00224 {
00225   if (written_flag)
00226   {
00227     if (!end_saved)
00228     {
00229       write_buffer();
00230       end_saved=1;
00231     }
00232   }
00233 }
00234 
00239 void test_smartlist::write_buffer(void)
00240 {
00241   int _nbytes=adptr_diff(bptr,buffer);
00242   if (_nbytes > 0)
00243   {
00244     const unsigned int nbytes = (unsigned int)_nbytes;
00245 
00246     written_flag=1;
00247     // get the current file position
00248     off_t pos=lseek(fp,0L,SEEK_CUR);
00249 
00250     // write the size of the next record into the file
00251 #if defined(OPT_LIB) && !defined(_MSC_VER)
00252     ::write(fp,&nbytes,sizeof(int));
00253 #else
00254     ssize_t ret = ::write(fp,&nbytes,sizeof(int));
00255     assert(ret != -1);
00256 #endif
00257 
00258     // write the record into the file
00259     ssize_t nw=::write(fp,buffer,nbytes);
00260     if (nw <= -1 || (unsigned int)nw != nbytes)
00261     {
00262       cerr << "Error writing to file " << filename << endl;
00263       ad_exit(1);
00264     }
00265     // reset the pointer to the beginning of the buffer
00266     bptr=buffer;
00267 
00268     // now write the previous file position into the file so we can back up
00269     // when we want to.
00270 #if defined(OPT_LIB) && !defined(_MSC_VER)
00271     ::write(fp,&pos,sizeof(off_t));
00272 #else
00273     ret = ::write(fp,&pos,sizeof(off_t));
00274     assert(ret != -1);
00275 #endif
00276 
00277     //cout << lseek(fp,0L,SEEK_CUR) << endl;
00278   }
00279 }
00280 
00285 void test_smartlist::read_buffer(void)
00286 {
00287   if (!written_flag)
00288   {
00289     if (direction ==-1)
00290       eof_flag=-1;
00291     else
00292       eof_flag=1;
00293   }
00294   else
00295   {
00296     off_t pos = sizeof(off_t);
00297     if (direction ==-1) // we are going backwards
00298     {
00299       // offset of the begining of the record is at the end
00300       // of the record
00301       lseek(fp,-pos,SEEK_CUR);
00302 #ifdef OPT_LIB
00303       ::read(fp, &pos, sizeof(off_t));
00304 #else
00305       ssize_t ret = read(fp,&pos,sizeof(off_t));
00306       assert(ret != -1);
00307 #endif
00308       // back up to the beginning of the record (plus record size)
00309       lseek(fp,pos,SEEK_SET);
00310       //*(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00311     }
00312     // get the record size
00313     unsigned int nbytes = 0;
00314 #ifdef OPT_LIB
00315     ::read(fp,&nbytes,sizeof(unsigned int));
00316 #else
00317     ssize_t ret = ::read(fp,&nbytes,sizeof(unsigned int));
00318     assert(ret != -1);
00319 #endif
00320     if (nbytes > bufsize)
00321     {
00322       cerr << "Error -- record size in file seems to be larger than"
00323        " the buffer it was created from " << endl
00324         << " buffer size is " << bufsize << " record size is supposedly "
00325         << nbytes << endl;
00326     }
00327     // now read the record into the buffer
00328     ssize_t nr = ::read(fp,buffer,nbytes);
00329     if (nr <= -1 || (size_t)nr != nbytes)
00330     {
00331       cerr << "Error reading -- should be " << nbytes << " got " << nr << endl;
00332       exit(1);
00333     }
00334     // reset the pointer to the beginning of the buffer
00335     bptr=buffer;
00336     recend=bptr+nbytes-1;
00337     if (direction ==-1) // we are going backwards
00338     {
00339       // backup the file pointer again
00340       lseek(fp,pos,SEEK_SET);
00341       // *(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00342     }
00343     else  // we are going forward
00344     {
00345       // skip over file postion entry in file
00346       lseek(fp, pos, SEEK_CUR);
00347     }
00348   }
00349 }
00350 
00355 void memcpy(const test_smartlist& _list, void* p, const size_t nsize)
00356 {
00357   ADUNCONST(test_smartlist,list)
00358   if (list.bptr+nsize-1 > list.buffend)
00359   {
00360     cerr << " Trying to write outside list buffer" << endl;
00361     exit(1);
00362   }
00363   memcpy(list.bptr,p,nsize);
00364   list.bptr+=nsize;
00365 }
00366 
00371 void memcpy(void* p, const test_smartlist & _list, const size_t nsize)
00372 {
00373   ADUNCONST(test_smartlist,list)
00374   if (list.bptr+nsize-1 > list.buffend)
00375   {
00376     cerr << " Trying to write outside list buffer" << endl;
00377     exit(1);
00378   }
00379   memcpy(p,list.bptr,nsize);
00380   list.bptr+=nsize;
00381 }
00382 
00387 void test_smartlist::operator-=(const int n)
00388 {
00389   if (bptr-n<buffer)
00390   {
00391     if (bptr != buffer)
00392     {
00393       cerr << " Sanity error in test_smartlist::operator -= (int)" << endl;
00394       exit(1);
00395     }
00396     else
00397     {
00398       // get previous record from the file
00399       read_buffer();
00400       bptr=recend-n+1;
00401     }
00402   }
00403   else
00404   {
00405     bptr-=n;
00406   }
00407 }
00408 
00413 void test_smartlist::operator+=(const int nsize)
00414 {
00415   if ( bptr+nsize-1 > buffend)
00416   {
00417     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00418     {
00419       read_buffer();
00420     }
00421     else
00422     {
00423       if ((unsigned int)nsize>bufsize)
00424       {
00425          cout << "Need to increase buffsize in list" << endl;
00426          exit(1);
00427       }
00428       write_buffer();
00429     }
00430   }
00431   else
00432   {
00433     bptr+=nsize;
00434   }
00435 }
00439 test_smartlist::~test_smartlist()
00440 {
00441   end_saved=0;
00442   eof_flag=0;
00443   noreadflag=0;
00444   written_flag=0;
00445   direction=0;
00446   bufsize=0;
00447 
00448   if (true_buffer)
00449   {
00450     delete [] true_buffer;
00451     true_buffer=0;
00452   }
00453   true_buffend=0;
00454   buffer=0;
00455   buffend=0;
00456   bptr=0;
00457   off_t pos=lseek(fp,0L,SEEK_END);
00458   int on1=-1;
00459   if ( (on1=option_match(ad_comm::argc,ad_comm::argv,"-fsize"))>-1)
00460   {
00461     if (ad_comm::global_logfile)
00462     {
00463       *ad_comm::global_logfile << "size of file " << filename
00464         << " = " << pos << endl;
00465     }
00466   }
00467   close(fp);
00468   fp=0;
00469 #if defined (_MSC_VER)
00470   remove(filename);
00471 #else
00472   unlink(filename);
00473 #endif
00474 }