ADMB Documentation  11.1.2532
 All Classes Files Functions Variables Typedefs Friends Defines
df1b2f10.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: df1b2f10.cpp 2500 2014-10-25 00:39:07Z 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 typedef int ssize_t;
00020 #else
00021   #include <unistd.h>
00022 #endif
00023 
00028 void test_smartlist::reset(void)
00029 {
00030   bptr=buffer;
00031   eof_flag=0;
00032   lseek(fp, 0L, SEEK_SET);
00033   written_flag=0;
00034   end_saved=0;
00035 }
00036 
00040 test_smartlist::test_smartlist(void)
00041 {
00042   bufsize=0;
00043   buffer=0;
00044   true_buffer=0;
00045   buffend=0;
00046   bptr=0;
00047   fp=-1;
00048 }
00049 
00054 test_smartlist::test_smartlist(unsigned int _bufsize,const adstring& _filename)
00055 {
00056   allocate(_bufsize,_filename);
00057 }
00058 
00063 void test_smartlist::allocate(unsigned int _bufsize,const adstring& _filename)
00064 {
00065   //cerr << "need to modify test_smartlist class for multibyte char" << endl;
00066   assert(sizeof(char) == 1);
00067 
00068   end_saved=0;
00069   eof_flag=0;
00070   noreadflag=0;
00071   written_flag=0;
00072   direction=0;
00073   bufsize=_bufsize;
00074   filename=_filename;
00075   //AD_ALLOCATE(true_buffer,char,bufsize+2*sizeof(double),df1b2_gradlist)
00076   if ((true_buffer=new char[(bufsize+2)*sizeof(double) ])==0)
00077   {
00078     cerr << "Allocation error in df1b2_gradlist" << endl;
00079     ad_exit(1);
00080   }
00081   doubleptr=(double*)true_buffer;
00082   true_buffend=true_buffer+bufsize+2*sizeof(double)-1;
00083   buffer=true_buffer+sizeof(double);
00084   *(double*)(true_buffer)=5678.9;
00085   *(double*)(true_buffer+bufsize+sizeof(double))=9876.5;
00086   //buffend=true_buffer+bufsize-1+sizeof(double);
00087   buffend=true_buffer+bufsize-1;
00088   bptr=buffer;
00089   fp=open((char*)(filename), O_RDWR | O_CREAT | O_TRUNC |
00090                    O_BINARY, S_IREAD | S_IWRITE);
00091   if (fp == -1)
00092   {
00093     cerr << "Error trying to open file " << filename
00094          << " in class test_smartlist " << endl;
00095     exit(1);
00096   }
00097 
00098   /*off_t pos=*/lseek(fp,0L,SEEK_CUR);
00099 }
00100 
00105 void test_smartlist::write(int n)
00106 {
00107   ssize_t nw = ::write(fp,buffer,n);
00108   if (nw<n)
00109   {
00110     cerr << "Error writing to file " << filename << endl;
00111     ad_exit(1);
00112   }
00113 }
00114 
00119 void test_smartlist::rewind(void)
00120 {
00121   bptr=buffer;
00122   if (written_flag)
00123   {
00124     lseek(fp,0L,SEEK_SET);
00125     // get the record size
00126     int nbytes = 0;
00127 #ifdef OPT_LIB
00128     ::read(fp,&nbytes,sizeof(int));
00129 #else
00130     ssize_t ret = ::read(fp,&nbytes,sizeof(int));
00131     assert(ret != -1);
00132     assert(nbytes >= 0);
00133 #endif
00134     if ((unsigned int)nbytes > bufsize)
00135     {
00136       cerr << "Error -- record size in file seems to be larger than"
00137        " the buffer it was created from " << endl
00138         << " buffer size is " << bufsize << " record size is supposedly "
00139         << nbytes << endl;
00140     }
00141 #ifdef OPT_LIB
00142     ::read(fp,buffer,nbytes);
00143 #else
00144     // now read the record into the buffer
00145     ret = ::read(fp,buffer,nbytes);
00146     assert(ret != -1);
00147 #endif
00148     //cout << "Number of bytes read " << nr << endl;
00149     // skip over file postion entry in file
00150     // so we are ready to read second record
00151     lseek(fp, (off_t)sizeof(off_t),SEEK_CUR);
00152   }
00153 }
00154 
00159 void test_smartlist::initialize(void)
00160 {
00161   end_saved=0;
00162   bptr=buffer;
00163   //int nbytes=0;
00164   written_flag=0;
00165   lseek(fp,0L,SEEK_SET);
00166   set_forward();
00167 }
00168 
00173 void test_smartlist::check_buffer_size(int nsize)
00174 {
00175   if ( bptr+nsize-1 > buffend)
00176   {
00177     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00178     {
00179       read_buffer();
00180     }
00181     else
00182     {
00183       if ((unsigned int)nsize>bufsize)
00184       {
00185          cout << "Need to increase buffsize in list" << endl;
00186          exit(1);
00187       }
00188       write_buffer();
00189     }
00190   }
00191 }
00192 
00197 void test_smartlist::restore_end(void)
00198 {
00199   if (written_flag)
00200   {
00201     if (end_saved)
00202     {
00203       read_buffer();
00204       set_recend();
00205     }
00206   }
00207 }
00208 
00213 void test_smartlist::save_end(void)
00214 {
00215   if (written_flag)
00216   {
00217     if (!end_saved)
00218     {
00219       write_buffer();
00220       end_saved=1;
00221     }
00222   }
00223 }
00224 
00229 void test_smartlist::write_buffer(void)
00230 {
00231   int nbytes=adptr_diff(bptr,buffer);
00232   if (nbytes)
00233   {
00234     written_flag=1;
00235     // get the current file position
00236     off_t pos=lseek(fp,0L,SEEK_CUR);
00237 
00238     // write the size of the next record into the file
00239 #ifdef OPT_LIB
00240     ::write(fp,&nbytes,sizeof(int));
00241 #else
00242     ssize_t ret = ::write(fp,&nbytes,sizeof(int));
00243     assert(ret != -1);
00244 #endif
00245 
00246     // write the record into the file
00247     ssize_t nw=::write(fp,buffer,nbytes);
00248     //cout << "Number of bytes written " << nw << endl;
00249     //cout << "buffer value = ";
00250     //for (int ii=0;ii<=25;ii++)
00251     //  cout << int (*(buffer+ii)) << " ";
00252     //cout << endl;
00253     if (nw<nbytes)
00254     {
00255       cerr << "Error writing to file " << filename << endl;
00256       ad_exit(1);
00257     }
00258     // reset the pointer to the beginning of the buffer
00259     bptr=buffer;
00260 
00261     // now write the previous file position into the file so we can back up
00262     // when we want to.
00263 #ifdef OPT_LIB
00264     ::write(fp,&pos,sizeof(off_t));
00265 #else
00266     ret = ::write(fp,&pos,sizeof(off_t));
00267     assert(ret != -1);
00268 #endif
00269 
00270     //cout << lseek(fp,0L,SEEK_CUR) << endl;
00271   }
00272 }
00273 
00278 void test_smartlist::read_buffer(void)
00279 {
00280   if (!written_flag)
00281   {
00282     if (direction ==-1)
00283       eof_flag=-1;
00284     else
00285       eof_flag=1;
00286   }
00287   else
00288   {
00289     off_t pos = sizeof(off_t);
00290     if (direction ==-1) // we are going backwards
00291     {
00292       // offset of the begining of the record is at the end
00293       // of the record
00294       lseek(fp,-pos,SEEK_CUR);
00295 #ifdef OPT_LIB
00296       ::read(fp, &pos, sizeof(off_t));
00297 #else
00298       ssize_t ret = read(fp,&pos,sizeof(off_t));
00299       assert(ret != -1);
00300 #endif
00301       // back up to the beginning of the record (plus record size)
00302       lseek(fp,pos,SEEK_SET);
00303       //*(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00304     }
00305     // get the record size
00306     int nbytes = 0;
00307 #ifdef OPT_LIB
00308     ::read(fp,&nbytes,sizeof(int));
00309 #else
00310     ssize_t ret = ::read(fp,&nbytes,sizeof(int));
00311     assert(ret != -1);
00312     assert(nbytes >= 0);
00313 #endif
00314     if ((unsigned int)nbytes > bufsize)
00315     {
00316       cerr << "Error -- record size in file seems to be larger than"
00317        " the buffer it was created from " << endl
00318         << " buffer size is " << bufsize << " record size is supposedly "
00319         << nbytes << endl;
00320     }
00321     // now read the record into the buffer
00322     ssize_t nr = ::read(fp,buffer,nbytes);
00323     assert(nr != -1);
00324     if (nr != nbytes)
00325     {
00326       cerr << "Error reading -- should be " << nbytes << " got " << nr << endl;
00327       exit(1);
00328     }
00329    /*
00330     cout << "Number of bytes read " << nr << endl;
00331     cout << "buffer value = ";
00332     for (int ii=0;ii<=25;ii++)
00333       cout << int (*(buffer+ii)) << " ";
00334     cout << endl;
00335     */
00336     // reset the pointer to the beginning of the buffer
00337     bptr=buffer;
00338     recend=bptr+nbytes-1;
00339     if (direction ==-1) // we are going backwards
00340     {
00341       // backup the file pointer again
00342       lseek(fp,pos,SEEK_SET);
00343       // *(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00344     }
00345     else  // we are going forward
00346     {
00347       // skip over file postion entry in file
00348       lseek(fp, pos, SEEK_CUR);
00349     }
00350   }
00351 }
00352 
00357 void memcpy(const test_smartlist& _list, void* p, const size_t nsize)
00358 {
00359   ADUNCONST(test_smartlist,list)
00360   if ( list.bptr+nsize-1 > list.buffend)
00361   {
00362     cerr << " Trying to write outside list buffer" << endl;
00363     exit(1);
00364   }
00365   memcpy(list.bptr,p,nsize);
00366   list.bptr+=nsize;
00367 }
00368 
00373 void memcpy(void* p, const test_smartlist & _list, const size_t nsize)
00374 {
00375   ADUNCONST(test_smartlist,list)
00376   if ( list.bptr+nsize-1 > list.buffend)
00377   {
00378     cerr << " Trying to write outside list buffer" << endl;
00379     exit(1);
00380   }
00381   memcpy(p,list.bptr,nsize);
00382   list.bptr+=nsize;
00383 }
00384 
00389 void test_smartlist::operator-=(int n)
00390 {
00391   if (bptr-n<buffer)
00392   {
00393     if (bptr != buffer)
00394     {
00395       cerr << " Sanity error in test_smartlist::operator -= (int)" << endl;
00396       exit(1);
00397     }
00398     else
00399     {
00400       // get previous record from the file
00401       read_buffer();
00402       bptr=recend-n+1;
00403     }
00404   }
00405   else
00406   {
00407     bptr-=n;
00408   }
00409 }
00410 
00415 void test_smartlist::operator+=(int nsize)
00416 {
00417   if ( bptr+nsize-1 > buffend)
00418   {
00419     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00420     {
00421       read_buffer();
00422     }
00423     else
00424     {
00425       if ((unsigned int)nsize>bufsize)
00426       {
00427          cout << "Need to increase buffsize in list" << endl;
00428          exit(1);
00429       }
00430       write_buffer();
00431     }
00432   }
00433   else
00434   {
00435     bptr+=nsize;
00436   }
00437 }
00441 test_smartlist::~test_smartlist()
00442 {
00443   end_saved=0;
00444   eof_flag=0;
00445   noreadflag=0;
00446   written_flag=0;
00447   direction=0;
00448   bufsize=0;
00449 
00450   if (true_buffer)
00451   {
00452     delete [] true_buffer;
00453     true_buffer=0;
00454   }
00455   true_buffend=0;
00456   buffer=0;
00457   buffend=0;
00458   bptr=0;
00459   off_t pos=lseek(fp,0L,SEEK_END);
00460   int on1=-1;
00461   if ( (on1=option_match(ad_comm::argc,ad_comm::argv,"-fsize"))>-1)
00462   {
00463     if (ad_comm::global_logfile)
00464     {
00465       *ad_comm::global_logfile << "size of file " << filename
00466         << " = " << pos << endl;
00467     }
00468   }
00469   close(fp);
00470   fp=0;
00471 #if defined (_MSC_VER)
00472   remove(filename);
00473 #else
00474   unlink(filename);
00475 #endif
00476 }