ADMB Documentation  11.1.2251
 All Classes Files Functions Variables Typedefs Friends Defines
df1b2f10.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: df1b2f10.cpp 1919 2014-04-22 22:02:01Z johnoel $
00003  *
00004  * Author: David Fournier
00005  * Copyright (c) 2008-2012 Regents of the University of California
00006  */
00011 #include <df1b2fun.h>
00012 
00017 void test_smartlist::reset(void)
00018 {
00019   bptr=buffer;
00020   eof_flag=0;
00021   lseek(fp, 0L, SEEK_SET);
00022   written_flag=0;
00023   end_saved=0;
00024 }
00025 
00029 test_smartlist::test_smartlist(void)
00030 {
00031   bufsize=0;
00032   buffer=0;
00033   true_buffer=0;
00034   buffend=0;
00035   bptr=0;
00036   fp=-1;
00037 }
00038 
00043 test_smartlist::test_smartlist(unsigned int _bufsize,const adstring& _filename)
00044 {
00045   allocate(_bufsize,_filename);
00046 }
00047 
00052 void test_smartlist::allocate(unsigned int _bufsize,const adstring& _filename)
00053 {
00054   if (sizeof(char)>1)
00055   {
00056     cerr << "need to modify test_smartlist class for multibyte char" << endl;
00057     exit(1);
00058   }
00059   end_saved=0;
00060   eof_flag=0;
00061   noreadflag=0;
00062   written_flag=0;
00063   direction=0;
00064   bufsize=_bufsize;
00065   filename=_filename;
00066   //AD_ALLOCATE(true_buffer,char,bufsize+2*sizeof(double),df1b2_gradlist)
00067   if ((true_buffer=new char[(bufsize+2)*sizeof(double) ])==0)
00068   {
00069     cerr << "Allocation error in df1b2_gradlist" << endl;
00070     ad_exit(1);
00071   }
00072   doubleptr=(double*)true_buffer;
00073   true_buffend=true_buffer+bufsize+2*sizeof(double)-1;
00074   buffer=true_buffer+sizeof(double);
00075   *(double*)(true_buffer)=5678.9;
00076   *(double*)(true_buffer+bufsize+sizeof(double))=9876.5;
00077   //buffend=true_buffer+bufsize-1+sizeof(double);
00078   buffend=true_buffer+bufsize-1;
00079   bptr=buffer;
00080   fp=open((char*)(filename), O_RDWR | O_CREAT | O_TRUNC |
00081                    O_BINARY, S_IREAD | S_IWRITE);
00082   if (fp == -1)
00083   {
00084     cerr << "Error trying to open file " << filename
00085          << " in class test_smartlist " << endl;
00086     exit(1);
00087   }
00088 
00089   /*off_t pos=*/lseek(fp,0L,SEEK_CUR);
00090 }
00091 
00096 void test_smartlist::write(int n)
00097 {
00098   int nw=::write(fp,buffer,n);
00099   if (nw<n)
00100   {
00101     cerr << "Error writing to file " << filename << endl;
00102     ad_exit(1);
00103   }
00104 }
00105 
00110 void test_smartlist::rewind(void)
00111 {
00112   bptr=buffer;
00113   unsigned int nbytes=0;
00114   if (written_flag)
00115   {
00116     lseek(fp,0L,SEEK_SET);
00117     // get the record size
00118     ::read(fp,&nbytes,sizeof(int));
00119     if (nbytes>bufsize)
00120     {
00121       cerr << "Error -- record size in file seems to be larger than"
00122        " the buffer it was created from " << endl
00123         << " buffer size is " << bufsize << " record size is supposedly "
00124         << nbytes << endl;
00125     }
00126     // now read the record into the buffer
00127     /*int nr=*/::read(fp,buffer,nbytes);
00128     //cout << "Number of bytes read " << nr << endl;
00129     // skip over file postion entry in file
00130     // so we are ready to read second record
00131     lseek(fp,long(sizeof(off_t)),SEEK_CUR);
00132   }
00133 }
00134 
00139 void test_smartlist::initialize(void)
00140 {
00141   end_saved=0;
00142   bptr=buffer;
00143   //int nbytes=0;
00144   written_flag=0;
00145   lseek(fp,0L,SEEK_SET);
00146   set_forward();
00147 }
00148 
00153 void test_smartlist::check_buffer_size(int nsize)
00154 {
00155   if ( bptr+nsize-1 > buffend)
00156   {
00157     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00158     {
00159       read_buffer();
00160     }
00161     else
00162     {
00163       if ((unsigned int)nsize>bufsize)
00164       {
00165          cout << "Need to increase buffsize in list" << endl;
00166          exit(1);
00167       }
00168       write_buffer();
00169     }
00170   }
00171 }
00172 
00177 void test_smartlist::restore_end(void)
00178 {
00179   if (written_flag)
00180   {
00181     if (end_saved)
00182     {
00183       read_buffer();
00184       set_recend();
00185     }
00186   }
00187 }
00188 
00193 void test_smartlist::save_end(void)
00194 {
00195   if (written_flag)
00196   {
00197     if (!end_saved)
00198     {
00199       write_buffer();
00200       end_saved=1;
00201     }
00202   }
00203 }
00204 
00209 void test_smartlist::write_buffer(void)
00210 {
00211   int nbytes=adptr_diff(bptr,buffer);
00212   if (nbytes)
00213   {
00214     written_flag=1;
00215     // get the current file position
00216     off_t pos=lseek(fp,0L,SEEK_CUR);
00217 
00218     // write the size of the next record into the file
00219     ::write(fp,&nbytes,sizeof(int));
00220 
00221     // write the record into the file
00222     int nw=::write(fp,buffer,nbytes);
00223     //cout << "Number of bytes written " << nw << endl;
00224     //cout << "buffer value = ";
00225     //for (int ii=0;ii<=25;ii++)
00226     //  cout << int (*(buffer+ii)) << " ";
00227     //cout << endl;
00228     if (nw<nbytes)
00229     {
00230       cerr << "Error writing to file " << filename << endl;
00231       ad_exit(1);
00232     }
00233     // reset the pointer to the beginning of the buffer
00234     bptr=buffer;
00235 
00236     // now write the previous file position into the file so we can back up
00237     // when we want to.
00238     ::write(fp,&pos,sizeof(off_t));
00239 
00240     //cout << lseek(fp,0L,SEEK_CUR) << endl;
00241   }
00242 }
00243 
00248 void test_smartlist::read_buffer(void)
00249 {
00250   if (!written_flag)
00251   {
00252     if (direction ==-1)
00253       eof_flag=-1;
00254     else
00255       eof_flag=1;
00256   }
00257   else
00258   {
00259     off_t pos;
00260     if (direction ==-1) // we are going backwards
00261     {
00262       // offset of the begining of the record is at the end
00263       // of the record
00264       lseek(fp,long(-sizeof(off_t)),SEEK_CUR);
00265       read(fp,&pos,sizeof(off_t));
00266       // back up to the beginning of the record (plus record size)
00267       lseek(fp,pos,SEEK_SET);
00268       //*(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00269     }
00270     // get the record size
00271     unsigned int nbytes = 0;
00272     ::read(fp,&nbytes,sizeof(int));
00273     if (nbytes>bufsize)
00274     {
00275       cerr << "Error -- record size in file seems to be larger than"
00276        " the buffer it was created from " << endl
00277         << " buffer size is " << bufsize << " record size is supposedly "
00278         << nbytes << endl;
00279     }
00280     // now read the record into the buffer
00281     unsigned int nr=::read(fp,buffer,nbytes);
00282     if (nr != nbytes)
00283     {
00284       cerr << "Error reading -- should be " << nbytes << " got " << nr << endl;
00285       exit(1);
00286     }
00287    /*
00288     cout << "Number of bytes read " << nr << endl;
00289     cout << "buffer value = ";
00290     for (int ii=0;ii<=25;ii++)
00291       cout << int (*(buffer+ii)) << " ";
00292     cout << endl;
00293     */
00294     // reset the pointer to the beginning of the buffer
00295     bptr=buffer;
00296     recend=bptr+nbytes-1;
00297     if (direction ==-1) // we are going backwards
00298     {
00299       // backup the file pointer again
00300       lseek(fp,pos,SEEK_SET);
00301       // *(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00302     }
00303     else  // we are going forward
00304     {
00305       // skip over file postion entry in file
00306       lseek(fp,long(sizeof(off_t)),SEEK_CUR);
00307     }
00308   }
00309 }
00310 
00315 void memcpy(const test_smartlist & _list,void * p,int nsize)
00316 {
00317   ADUNCONST(test_smartlist,list)
00318   if ( list.bptr+nsize-1 > list.buffend)
00319   {
00320     cerr << " Trying to write outside list buffer" << endl;
00321     exit(1);
00322   }
00323   memcpy(list.bptr,p,nsize);
00324   list.bptr+=nsize;
00325 }
00326 
00331 void memcpy(void * p,const test_smartlist & _list,int nsize)
00332 {
00333   ADUNCONST(test_smartlist,list)
00334   if ( list.bptr+nsize-1 > list.buffend)
00335   {
00336     cerr << " Trying to write outside list buffer" << endl;
00337     exit(1);
00338   }
00339   memcpy(p,list.bptr,nsize);
00340   list.bptr+=nsize;
00341 }
00342 
00347 void test_smartlist::operator-=(int n)
00348 {
00349   if (bptr-n<buffer)
00350   {
00351     if (bptr != buffer)
00352     {
00353       cerr << " Sanity error in test_smartlist::operator -= (int)" << endl;
00354       exit(1);
00355     }
00356     else
00357     {
00358       // get previous record from the file
00359       read_buffer();
00360       bptr=recend-n+1;
00361     }
00362   }
00363   else
00364   {
00365     bptr-=n;
00366   }
00367 }
00368 
00373 void test_smartlist::operator+=(int nsize)
00374 {
00375   if ( bptr+nsize-1 > buffend)
00376   {
00377     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00378     {
00379       read_buffer();
00380     }
00381     else
00382     {
00383       if ((unsigned int)nsize>bufsize)
00384       {
00385          cout << "Need to increase buffsize in list" << endl;
00386          exit(1);
00387       }
00388       write_buffer();
00389     }
00390   }
00391   else
00392   {
00393     bptr+=nsize;
00394   }
00395 }
00399 test_smartlist::~test_smartlist()
00400 {
00401   end_saved=0;
00402   eof_flag=0;
00403   noreadflag=0;
00404   written_flag=0;
00405   direction=0;
00406   bufsize=0;
00407 
00408   if (true_buffer)
00409   {
00410     delete [] true_buffer;
00411     true_buffer=0;
00412   }
00413   true_buffend=0;
00414   buffer=0;
00415   buffend=0;
00416   bptr=0;
00417   off_t pos=lseek(fp,0L,SEEK_END);
00418   int on1=-1;
00419   if ( (on1=option_match(ad_comm::argc,ad_comm::argv,"-fsize"))>-1)
00420   {
00421     if (ad_comm::global_logfile)
00422     {
00423       *ad_comm::global_logfile << "size of file " << filename
00424         << " = " << pos << endl;
00425     }
00426   }
00427   close(fp);
00428   fp=0;
00429 #if defined (_MSC_VER)
00430   remove(filename);
00431 #else
00432   unlink(filename);
00433 #endif
00434 }