ADMB Documentation  11.1.2364
 All Classes Files Functions Variables Typedefs Friends Defines
df1b2f10.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: df1b2f10.cpp 2356 2014-09-16 19:50:01Z 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 #endif
00021 
00026 void test_smartlist::reset(void)
00027 {
00028   bptr=buffer;
00029   eof_flag=0;
00030   lseek(fp, 0L, SEEK_SET);
00031   written_flag=0;
00032   end_saved=0;
00033 }
00034 
00038 test_smartlist::test_smartlist(void)
00039 {
00040   bufsize=0;
00041   buffer=0;
00042   true_buffer=0;
00043   buffend=0;
00044   bptr=0;
00045   fp=-1;
00046 }
00047 
00052 test_smartlist::test_smartlist(unsigned int _bufsize,const adstring& _filename)
00053 {
00054   allocate(_bufsize,_filename);
00055 }
00056 
00061 void test_smartlist::allocate(unsigned int _bufsize,const adstring& _filename)
00062 {
00063   //cerr << "need to modify test_smartlist class for multibyte char" << endl;
00064   assert(sizeof(char) == 1);
00065 
00066   end_saved=0;
00067   eof_flag=0;
00068   noreadflag=0;
00069   written_flag=0;
00070   direction=0;
00071   bufsize=_bufsize;
00072   filename=_filename;
00073   //AD_ALLOCATE(true_buffer,char,bufsize+2*sizeof(double),df1b2_gradlist)
00074   if ((true_buffer=new char[(bufsize+2)*sizeof(double) ])==0)
00075   {
00076     cerr << "Allocation error in df1b2_gradlist" << endl;
00077     ad_exit(1);
00078   }
00079   doubleptr=(double*)true_buffer;
00080   true_buffend=true_buffer+bufsize+2*sizeof(double)-1;
00081   buffer=true_buffer+sizeof(double);
00082   *(double*)(true_buffer)=5678.9;
00083   *(double*)(true_buffer+bufsize+sizeof(double))=9876.5;
00084   //buffend=true_buffer+bufsize-1+sizeof(double);
00085   buffend=true_buffer+bufsize-1;
00086   bptr=buffer;
00087   fp=open((char*)(filename), O_RDWR | O_CREAT | O_TRUNC |
00088                    O_BINARY, S_IREAD | S_IWRITE);
00089   if (fp == -1)
00090   {
00091     cerr << "Error trying to open file " << filename
00092          << " in class test_smartlist " << endl;
00093     exit(1);
00094   }
00095 
00096   /*off_t pos=*/lseek(fp,0L,SEEK_CUR);
00097 }
00098 
00103 void test_smartlist::write(int n)
00104 {
00105   ssize_t nw = ::write(fp,buffer,n);
00106   if (nw<n)
00107   {
00108     cerr << "Error writing to file " << filename << endl;
00109     ad_exit(1);
00110   }
00111 }
00112 
00117 void test_smartlist::rewind(void)
00118 {
00119   bptr=buffer;
00120   if (written_flag)
00121   {
00122     lseek(fp,0L,SEEK_SET);
00123     // get the record size
00124     int nbytes = 0;
00125 #ifdef OPT_LIB
00126     ::read(fp,&nbytes,sizeof(int));
00127 #else
00128     ssize_t ret = ::read(fp,&nbytes,sizeof(int));
00129     assert(ret != -1);
00130     assert(nbytes >= 0);
00131 #endif
00132     if ((unsigned int)nbytes > bufsize)
00133     {
00134       cerr << "Error -- record size in file seems to be larger than"
00135        " the buffer it was created from " << endl
00136         << " buffer size is " << bufsize << " record size is supposedly "
00137         << nbytes << endl;
00138     }
00139 #ifdef OPT_LIB
00140     ::read(fp,buffer,nbytes);
00141 #else
00142     // now read the record into the buffer
00143     ret = ::read(fp,buffer,nbytes);
00144     assert(ret != -1);
00145 #endif
00146     //cout << "Number of bytes read " << nr << endl;
00147     // skip over file postion entry in file
00148     // so we are ready to read second record
00149     lseek(fp,long(sizeof(off_t)),SEEK_CUR);
00150   }
00151 }
00152 
00157 void test_smartlist::initialize(void)
00158 {
00159   end_saved=0;
00160   bptr=buffer;
00161   //int nbytes=0;
00162   written_flag=0;
00163   lseek(fp,0L,SEEK_SET);
00164   set_forward();
00165 }
00166 
00171 void test_smartlist::check_buffer_size(int nsize)
00172 {
00173   if ( bptr+nsize-1 > buffend)
00174   {
00175     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00176     {
00177       read_buffer();
00178     }
00179     else
00180     {
00181       if ((unsigned int)nsize>bufsize)
00182       {
00183          cout << "Need to increase buffsize in list" << endl;
00184          exit(1);
00185       }
00186       write_buffer();
00187     }
00188   }
00189 }
00190 
00195 void test_smartlist::restore_end(void)
00196 {
00197   if (written_flag)
00198   {
00199     if (end_saved)
00200     {
00201       read_buffer();
00202       set_recend();
00203     }
00204   }
00205 }
00206 
00211 void test_smartlist::save_end(void)
00212 {
00213   if (written_flag)
00214   {
00215     if (!end_saved)
00216     {
00217       write_buffer();
00218       end_saved=1;
00219     }
00220   }
00221 }
00222 
00227 void test_smartlist::write_buffer(void)
00228 {
00229   int nbytes=adptr_diff(bptr,buffer);
00230   if (nbytes)
00231   {
00232     written_flag=1;
00233     // get the current file position
00234     off_t pos=lseek(fp,0L,SEEK_CUR);
00235 
00236     // write the size of the next record into the file
00237 #ifdef OPT_LIB
00238     ::write(fp,&nbytes,sizeof(int));
00239 #else
00240     ssize_t ret = ::write(fp,&nbytes,sizeof(int));
00241     assert(ret != -1);
00242 #endif
00243 
00244     // write the record into the file
00245     ssize_t nw=::write(fp,buffer,nbytes);
00246     //cout << "Number of bytes written " << nw << endl;
00247     //cout << "buffer value = ";
00248     //for (int ii=0;ii<=25;ii++)
00249     //  cout << int (*(buffer+ii)) << " ";
00250     //cout << endl;
00251     if (nw<nbytes)
00252     {
00253       cerr << "Error writing to file " << filename << endl;
00254       ad_exit(1);
00255     }
00256     // reset the pointer to the beginning of the buffer
00257     bptr=buffer;
00258 
00259     // now write the previous file position into the file so we can back up
00260     // when we want to.
00261 #ifdef OPT_LIB
00262     ::write(fp,&pos,sizeof(off_t));
00263 #else
00264     ret = ::write(fp,&pos,sizeof(off_t));
00265     assert(ret != -1);
00266 #endif
00267 
00268     //cout << lseek(fp,0L,SEEK_CUR) << endl;
00269   }
00270 }
00271 
00276 void test_smartlist::read_buffer(void)
00277 {
00278   if (!written_flag)
00279   {
00280     if (direction ==-1)
00281       eof_flag=-1;
00282     else
00283       eof_flag=1;
00284   }
00285   else
00286   {
00287     off_t pos = sizeof(off_t);
00288     if (direction ==-1) // we are going backwards
00289     {
00290       // offset of the begining of the record is at the end
00291       // of the record
00292       lseek(fp,-pos,SEEK_CUR);
00293 #ifdef OPT_LIB
00294       ::read(fp, &pos, sizeof(off_t));
00295 #else
00296       ssize_t ret = read(fp,&pos,sizeof(off_t));
00297       assert(ret != -1);
00298 #endif
00299       // back up to the beginning of the record (plus record size)
00300       lseek(fp,pos,SEEK_SET);
00301       //*(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00302     }
00303     // get the record size
00304     int nbytes = 0;
00305 #ifdef OPT_LIB
00306     ::read(fp,&nbytes,sizeof(int));
00307 #else
00308     ssize_t ret = ::read(fp,&nbytes,sizeof(int));
00309     assert(ret != -1);
00310     assert(nbytes >= 0);
00311 #endif
00312     if ((unsigned int)nbytes > bufsize)
00313     {
00314       cerr << "Error -- record size in file seems to be larger than"
00315        " the buffer it was created from " << endl
00316         << " buffer size is " << bufsize << " record size is supposedly "
00317         << nbytes << endl;
00318     }
00319     // now read the record into the buffer
00320     ssize_t nr = ::read(fp,buffer,nbytes);
00321     assert(nr != -1);
00322     if (nr != nbytes)
00323     {
00324       cerr << "Error reading -- should be " << nbytes << " got " << nr << endl;
00325       exit(1);
00326     }
00327    /*
00328     cout << "Number of bytes read " << nr << endl;
00329     cout << "buffer value = ";
00330     for (int ii=0;ii<=25;ii++)
00331       cout << int (*(buffer+ii)) << " ";
00332     cout << endl;
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,int 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,int 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-=(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+=(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 }