ADMB Documentation  11.1.2274
 All Classes Files Functions Variables Typedefs Friends Defines
df1b2f10.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: df1b2f10.cpp 2269 2014-08-29 00:10:02Z johnoel $
00003  *
00004  * Author: David Fournier
00005  * Copyright (c) 2008-2012 Regents of the University of California
00006  */
00011 #include <df1b2fun.h>
00012 #include <cassert>
00013 
00014 #ifdef _MSC_VER
00015 typedef int ssize_t;
00016 #endif
00017 
00022 void test_smartlist::reset(void)
00023 {
00024   bptr=buffer;
00025   eof_flag=0;
00026   lseek(fp, 0L, SEEK_SET);
00027   written_flag=0;
00028   end_saved=0;
00029 }
00030 
00034 test_smartlist::test_smartlist(void)
00035 {
00036   bufsize=0;
00037   buffer=0;
00038   true_buffer=0;
00039   buffend=0;
00040   bptr=0;
00041   fp=-1;
00042 }
00043 
00048 test_smartlist::test_smartlist(unsigned int _bufsize,const adstring& _filename)
00049 {
00050   allocate(_bufsize,_filename);
00051 }
00052 
00057 void test_smartlist::allocate(unsigned int _bufsize,const adstring& _filename)
00058 {
00059   if (sizeof(char)>1)
00060   {
00061     cerr << "need to modify test_smartlist class for multibyte char" << endl;
00062     exit(1);
00063   }
00064   end_saved=0;
00065   eof_flag=0;
00066   noreadflag=0;
00067   written_flag=0;
00068   direction=0;
00069   bufsize=_bufsize;
00070   filename=_filename;
00071   //AD_ALLOCATE(true_buffer,char,bufsize+2*sizeof(double),df1b2_gradlist)
00072   if ((true_buffer=new char[(bufsize+2)*sizeof(double) ])==0)
00073   {
00074     cerr << "Allocation error in df1b2_gradlist" << endl;
00075     ad_exit(1);
00076   }
00077   doubleptr=(double*)true_buffer;
00078   true_buffend=true_buffer+bufsize+2*sizeof(double)-1;
00079   buffer=true_buffer+sizeof(double);
00080   *(double*)(true_buffer)=5678.9;
00081   *(double*)(true_buffer+bufsize+sizeof(double))=9876.5;
00082   //buffend=true_buffer+bufsize-1+sizeof(double);
00083   buffend=true_buffer+bufsize-1;
00084   bptr=buffer;
00085   fp=open((char*)(filename), O_RDWR | O_CREAT | O_TRUNC |
00086                    O_BINARY, S_IREAD | S_IWRITE);
00087   if (fp == -1)
00088   {
00089     cerr << "Error trying to open file " << filename
00090          << " in class test_smartlist " << endl;
00091     exit(1);
00092   }
00093 
00094   /*off_t pos=*/lseek(fp,0L,SEEK_CUR);
00095 }
00096 
00101 void test_smartlist::write(int n)
00102 {
00103   int nw=::write(fp,buffer,n);
00104   if (nw<n)
00105   {
00106     cerr << "Error writing to file " << filename << endl;
00107     ad_exit(1);
00108   }
00109 }
00110 
00115 void test_smartlist::rewind(void)
00116 {
00117   bptr=buffer;
00118   unsigned int nbytes=0;
00119   if (written_flag)
00120   {
00121     lseek(fp,0L,SEEK_SET);
00122     // get the record size
00123     ssize_t ret = ::read(fp,&nbytes,sizeof(int));
00124     assert(ret != -1);
00125     if (nbytes>bufsize)
00126     {
00127       cerr << "Error -- record size in file seems to be larger than"
00128        " the buffer it was created from " << endl
00129         << " buffer size is " << bufsize << " record size is supposedly "
00130         << nbytes << endl;
00131     }
00132     // now read the record into the buffer
00133     ret = ::read(fp,buffer,nbytes);
00134     assert(ret != -1);
00135     //cout << "Number of bytes read " << nr << endl;
00136     // skip over file postion entry in file
00137     // so we are ready to read second record
00138     lseek(fp,long(sizeof(off_t)),SEEK_CUR);
00139   }
00140 }
00141 
00146 void test_smartlist::initialize(void)
00147 {
00148   end_saved=0;
00149   bptr=buffer;
00150   //int nbytes=0;
00151   written_flag=0;
00152   lseek(fp,0L,SEEK_SET);
00153   set_forward();
00154 }
00155 
00160 void test_smartlist::check_buffer_size(int nsize)
00161 {
00162   if ( bptr+nsize-1 > buffend)
00163   {
00164     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00165     {
00166       read_buffer();
00167     }
00168     else
00169     {
00170       if ((unsigned int)nsize>bufsize)
00171       {
00172          cout << "Need to increase buffsize in list" << endl;
00173          exit(1);
00174       }
00175       write_buffer();
00176     }
00177   }
00178 }
00179 
00184 void test_smartlist::restore_end(void)
00185 {
00186   if (written_flag)
00187   {
00188     if (end_saved)
00189     {
00190       read_buffer();
00191       set_recend();
00192     }
00193   }
00194 }
00195 
00200 void test_smartlist::save_end(void)
00201 {
00202   if (written_flag)
00203   {
00204     if (!end_saved)
00205     {
00206       write_buffer();
00207       end_saved=1;
00208     }
00209   }
00210 }
00211 
00216 void test_smartlist::write_buffer(void)
00217 {
00218   int nbytes=adptr_diff(bptr,buffer);
00219   if (nbytes)
00220   {
00221     written_flag=1;
00222     // get the current file position
00223     off_t pos=lseek(fp,0L,SEEK_CUR);
00224 
00225     // write the size of the next record into the file
00226     ssize_t ret = ::write(fp,&nbytes,sizeof(int));
00227     assert(ret != -1);
00228 
00229     // write the record into the file
00230     int nw=::write(fp,buffer,nbytes);
00231     //cout << "Number of bytes written " << nw << endl;
00232     //cout << "buffer value = ";
00233     //for (int ii=0;ii<=25;ii++)
00234     //  cout << int (*(buffer+ii)) << " ";
00235     //cout << endl;
00236     if (nw<nbytes)
00237     {
00238       cerr << "Error writing to file " << filename << endl;
00239       ad_exit(1);
00240     }
00241     // reset the pointer to the beginning of the buffer
00242     bptr=buffer;
00243 
00244     // now write the previous file position into the file so we can back up
00245     // when we want to.
00246     ret = ::write(fp,&pos,sizeof(off_t));
00247     assert(ret != -1);
00248 
00249     //cout << lseek(fp,0L,SEEK_CUR) << endl;
00250   }
00251 }
00252 
00257 void test_smartlist::read_buffer(void)
00258 {
00259   if (!written_flag)
00260   {
00261     if (direction ==-1)
00262       eof_flag=-1;
00263     else
00264       eof_flag=1;
00265   }
00266   else
00267   {
00268     off_t pos;
00269     if (direction ==-1) // we are going backwards
00270     {
00271       // offset of the begining of the record is at the end
00272       // of the record
00273       lseek(fp,long(-sizeof(off_t)),SEEK_CUR);
00274       ssize_t ret = read(fp,&pos,sizeof(off_t));
00275       assert(ret != -1);
00276       // back up to the beginning of the record (plus record size)
00277       lseek(fp,pos,SEEK_SET);
00278       //*(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00279     }
00280     // get the record size
00281     unsigned int nbytes = 0;
00282     ssize_t ret = ::read(fp,&nbytes,sizeof(int));
00283     assert(ret != -1);
00284     if (nbytes>bufsize)
00285     {
00286       cerr << "Error -- record size in file seems to be larger than"
00287        " the buffer it was created from " << endl
00288         << " buffer size is " << bufsize << " record size is supposedly "
00289         << nbytes << endl;
00290     }
00291     // now read the record into the buffer
00292     ssize_t nr = ::read(fp,buffer,nbytes);
00293     assert(ret != -1);
00294     if ((unsigned int)nr != nbytes)
00295     {
00296       cerr << "Error reading -- should be " << nbytes << " got " << nr << endl;
00297       exit(1);
00298     }
00299    /*
00300     cout << "Number of bytes read " << nr << endl;
00301     cout << "buffer value = ";
00302     for (int ii=0;ii<=25;ii++)
00303       cout << int (*(buffer+ii)) << " ";
00304     cout << endl;
00305     */
00306     // reset the pointer to the beginning of the buffer
00307     bptr=buffer;
00308     recend=bptr+nbytes-1;
00309     if (direction ==-1) // we are going backwards
00310     {
00311       // backup the file pointer again
00312       lseek(fp,pos,SEEK_SET);
00313       // *(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00314     }
00315     else  // we are going forward
00316     {
00317       // skip over file postion entry in file
00318       lseek(fp,long(sizeof(off_t)),SEEK_CUR);
00319     }
00320   }
00321 }
00322 
00327 void memcpy(const test_smartlist & _list,void * p,int nsize)
00328 {
00329   ADUNCONST(test_smartlist,list)
00330   if ( list.bptr+nsize-1 > list.buffend)
00331   {
00332     cerr << " Trying to write outside list buffer" << endl;
00333     exit(1);
00334   }
00335   memcpy(list.bptr,p,nsize);
00336   list.bptr+=nsize;
00337 }
00338 
00343 void memcpy(void * p,const test_smartlist & _list,int nsize)
00344 {
00345   ADUNCONST(test_smartlist,list)
00346   if ( list.bptr+nsize-1 > list.buffend)
00347   {
00348     cerr << " Trying to write outside list buffer" << endl;
00349     exit(1);
00350   }
00351   memcpy(p,list.bptr,nsize);
00352   list.bptr+=nsize;
00353 }
00354 
00359 void test_smartlist::operator-=(int n)
00360 {
00361   if (bptr-n<buffer)
00362   {
00363     if (bptr != buffer)
00364     {
00365       cerr << " Sanity error in test_smartlist::operator -= (int)" << endl;
00366       exit(1);
00367     }
00368     else
00369     {
00370       // get previous record from the file
00371       read_buffer();
00372       bptr=recend-n+1;
00373     }
00374   }
00375   else
00376   {
00377     bptr-=n;
00378   }
00379 }
00380 
00385 void test_smartlist::operator+=(int nsize)
00386 {
00387   if ( bptr+nsize-1 > buffend)
00388   {
00389     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00390     {
00391       read_buffer();
00392     }
00393     else
00394     {
00395       if ((unsigned int)nsize>bufsize)
00396       {
00397          cout << "Need to increase buffsize in list" << endl;
00398          exit(1);
00399       }
00400       write_buffer();
00401     }
00402   }
00403   else
00404   {
00405     bptr+=nsize;
00406   }
00407 }
00411 test_smartlist::~test_smartlist()
00412 {
00413   end_saved=0;
00414   eof_flag=0;
00415   noreadflag=0;
00416   written_flag=0;
00417   direction=0;
00418   bufsize=0;
00419 
00420   if (true_buffer)
00421   {
00422     delete [] true_buffer;
00423     true_buffer=0;
00424   }
00425   true_buffend=0;
00426   buffer=0;
00427   buffend=0;
00428   bptr=0;
00429   off_t pos=lseek(fp,0L,SEEK_END);
00430   int on1=-1;
00431   if ( (on1=option_match(ad_comm::argc,ad_comm::argv,"-fsize"))>-1)
00432   {
00433     if (ad_comm::global_logfile)
00434     {
00435       *ad_comm::global_logfile << "size of file " << filename
00436         << " = " << pos << endl;
00437     }
00438   }
00439   close(fp);
00440   fp=0;
00441 #if defined (_MSC_VER)
00442   remove(filename);
00443 #else
00444   unlink(filename);
00445 #endif
00446 }