ADMB Documentation  11.1.2192
 All Classes Files Functions Variables Typedefs Friends Defines
df1b2f13.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: df1b2f13.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 fixed_smartlist::reset(void)
00018 {
00019   end_saved=0;
00020   bptr=buffer;
00021   eof_flag=0;
00022   /*off_t pos=*/lseek(fp,0L,SEEK_CUR);
00023   endof_file_ptr=lseek(fp,0L,SEEK_SET);
00024   written_flag=0;
00025 }
00026 
00031 fixed_smartlist::fixed_smartlist(void)
00032 {
00033   nentries=0;
00034   bufsize=0;
00035   buffer=0;
00036   true_buffer=0;
00037   buffend=0;
00038   bptr=0;
00039   fp=-1;
00040 }
00041 
00046 fixed_smartlist::fixed_smartlist(unsigned int _bufsize,
00047   const adstring& _filename)
00048 {
00049   allocate(_bufsize,_filename);
00050 }
00051 void fixed_smartlist::allocate(unsigned int _bufsize,const adstring& _filename)
00052 {
00053   nentries=_bufsize/sizeof(fixed_list_entry);
00054   end_saved=0;
00055   eof_flag=0;
00056   noreadflag=0;
00057   written_flag=0;
00058   direction=0;
00059   bufsize=_bufsize;
00060   filename=_filename;
00061   AD_ALLOCATE(true_buffer,fixed_list_entry,nentries+2,df1b2_gradlist)
00062   doubleptr=(double*)true_buffer;
00063   true_buffend=true_buffer+nentries+1;
00064   buffer=true_buffer+1;
00065   buffend=true_buffend-2;
00066   bptr=buffer;
00067   true_buffer->numbytes=5678;
00068   //int(true_buffer->pf)=1234;
00069   true_buffend->numbytes=9999;
00070   //int(true_buffend->pf)=6666;
00071   fp=open((char*)(filename), O_RDWR | O_CREAT | O_TRUNC |
00072                    O_BINARY, S_IREAD | S_IWRITE);
00073   if (fp == -1)
00074   {
00075     cerr << "Error trying to open file " << filename
00076          << " in class fixed_smartlist " << endl;
00077     ad_exit(1);
00078   }
00079 
00080   /*off_t pos=*/lseek(fp,0L,SEEK_CUR);
00081 }
00082 
00087 void fixed_smartlist::write(int n)
00088 {
00089   int nw=::write(fp,buffer,n);
00090   if (nw<n)
00091   {
00092     cerr << "Error writing to file " << filename << endl;
00093     ad_exit(1);
00094   }
00095 }
00096 
00101 void fixed_smartlist::rewind(void)
00102 {
00103   bptr=buffer;
00104   unsigned int nbytes=0;
00105   eof_flag=0;
00106   if (written_flag)
00107   {
00108     lseek(fp,0L,SEEK_SET);
00109     // get the record size
00110     ::read(fp,&nbytes,sizeof(int));
00111     //cout << nbytes << endl;
00112     if (nbytes>bufsize)
00113     {
00114       cerr << "Error -- record size in file seems to be larger than"
00115        " the buffer it was created from " << endl
00116         << " buffer size is " << bufsize << " record size is supposedly "
00117         << nbytes << endl;
00118       ad_exit(1);
00119     }
00120     // now read the record into the buffer
00121     /*int nr=*/::read(fp,buffer,nbytes);
00122     //cout << "Number of bytes read " << nr << endl;
00123     // skip over file postion entry in file
00124     // so we are ready to read second record
00125     lseek(fp,long(sizeof(off_t)),SEEK_CUR);
00126   }
00127 }
00128 
00133 void fixed_smartlist::initialize(void)
00134 {
00135   end_saved=0;
00136   eof_flag=0;
00137   bptr=buffer;
00138   //int nbytes=0;
00139   written_flag=0;
00140   lseek(fp,0L,SEEK_SET);
00141   set_forward();
00142 }
00143 
00148 void fixed_smartlist::check_buffer_size(int nsize)
00149 {
00150   if ( bptr+nsize-1 > buffend)
00151   {
00152     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00153     {
00154       read_buffer();
00155     }
00156     else
00157     {
00158       if ((unsigned int)nsize>bufsize)
00159       {
00160          cout << "Need to increase buffsize in list" << endl;
00161          exit(1);
00162       }
00163       write_buffer();
00164     }
00165   }
00166 }
00167 
00172 void fixed_smartlist::restore_end(void)
00173 {
00174   if (written_flag)
00175   {
00176     if (end_saved)
00177     {
00178       /*off_t ipos=*/lseek(fp,0L,SEEK_END);
00179       lseek(fp,endof_file_ptr,SEEK_SET);
00180       read_buffer();
00181       set_recend();
00182     }
00183   }
00184 }
00185 
00190 void fixed_smartlist::save_end(void)
00191 {
00192   if (written_flag)
00193   {
00194     if (!end_saved)
00195     {
00196       write_buffer_one_less();
00197       end_saved=1;
00198     }
00199   }
00200 }
00201 
00206 void fixed_smartlist::write_buffer_one_less(void)
00207 {
00208   int nbytes=adptr_diff(bptr,buffer);
00209   if (nbytes)
00210   {
00211     written_flag=1;
00212     // get the current file position
00213     off_t pos=lseek(fp,0L,SEEK_CUR);
00214 
00215     // write the size of the next record into the file
00216     //cout << nbytes << endl;
00217     ::write(fp,&nbytes,sizeof(int));
00218 
00219     // write the record into the file
00220     int nw=::write(fp,buffer,nbytes);
00221     //cout << "Number of bytes written 1less " << nw
00222      //    << " bptr value =  " << bptr << endl;
00223     //for (int ii=0;ii<=25;ii++)
00224     //  cout << int (*(buffer+ii)) << " ";
00225     //cout << endl;
00226     if (nw<nbytes)
00227     {
00228       cerr << "Error writing to file " << filename << endl;
00229       ad_exit(1);
00230     }
00231     // reset the pointer to the beginning of the buffer
00232     bptr=buffer;
00233 
00234     // now write the previous file position into the file so we can back up
00235     // when we want to.
00236     ::write(fp,&pos,sizeof(off_t));
00237 
00238     endof_file_ptr=lseek(fp,0L,SEEK_CUR);
00239     //cout << lseek(fp,0L,SEEK_CUR) << endl;
00240   }
00241 }
00242 
00247 void fixed_smartlist::write_buffer(void)
00248 {
00249   unsigned int nbytes=adptr_diff(bptr+1,buffer);
00250   if (nbytes>bufsize)
00251   {
00252     cerr << "n bytes > bufsize in "
00253       "fixed_smartlist::write_buffer(void) this can't happen!" << endl;
00254   }
00255   if (nbytes)
00256   {
00257     written_flag=1;
00258     // get the current file position
00259     off_t pos=lseek(fp,0L,SEEK_CUR);
00260 
00261     // write the size of the next record into the file
00262     ::write(fp,&nbytes,sizeof(int));
00263 
00264     // write the record into the file
00265     unsigned int nw=::write(fp,buffer,nbytes);
00266     //cout << "Number of bytes written " << nw
00267      //    << " bptr value =  " << bptr << endl;
00268     //for (int ii=0;ii<=25;ii++)
00269     //  cout << int (*(buffer+ii)) << " ";
00270     //cout << endl;
00271     if (nw<nbytes)
00272     {
00273       cerr << "Error writing to file " << filename << endl;
00274       ad_exit(1);
00275     }
00276     // reset the pointer to the beginning of the buffer
00277     bptr=buffer;
00278 
00279     // now write the previous file position into the file so we can back up
00280     // when we want to.
00281     ::write(fp,&pos,sizeof(off_t));
00282 
00283     endof_file_ptr=lseek(fp,0L,SEEK_CUR);
00284     //cout << lseek(fp,0L,SEEK_CUR) << endl;
00285   }
00286 }
00287 
00292 void fixed_smartlist::read_buffer(void)
00293 {
00294   off_t pos;
00295   unsigned int nbytes;
00296   if (!written_flag)
00297   {
00298     if (direction ==-1)
00299       eof_flag=-1;
00300     else
00301       eof_flag=1;
00302   }
00303   else
00304   {
00305     if (direction ==-1) // we are going backwards
00306     {
00307       off_t ipos=lseek(fp,0L,SEEK_CUR);
00308       if (ipos ==0)
00309       {
00310         eof_flag=-1;
00311         return;
00312       }
00313       // offset of the begining of the record is at the end
00314       // of the record
00315       lseek(fp,long(-sizeof(off_t)),SEEK_CUR);
00316       read(fp,&pos,sizeof(off_t));
00317       // back up to the beginning of the record (plus record size)
00318       lseek(fp,pos,SEEK_SET);
00319       //*(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00320     }
00321     // get the record size
00322     ::read(fp,&nbytes,sizeof(int));
00323     if (nbytes>bufsize)
00324     {
00325       cerr << "Error -- record size in file seems to be larger than"
00326        " the buffer it was created from " << endl
00327         << " buffer size is " << bufsize << " record size is supposedly "
00328         << nbytes << endl;
00329       ad_exit(1);
00330     }
00331     // now read the record into the buffer
00332     unsigned int nr=::read(fp,buffer,nbytes);
00333     if (nr != nbytes)
00334     {
00335       cerr << "Error reading -- should be " << nbytes << " got " << nr << endl;
00336       exit(1);
00337     }
00338 
00339     //cout << "Number of bytes read " << nr << endl;
00340    /*
00341     cout << "buffer value = ";
00342     for (int ii=0;ii<=2;ii++)
00343       cout << *(buffer+ii) << " ";
00344     cout << endl;
00345     */
00346 
00347     // reset the pointer to the beginning of the buffer
00348     bptr=buffer;
00349     int ns=nbytes/sizeof(fixed_list_entry);
00350     recend=bptr+ns-1;
00351     //cout << "Number of bytes read " << nr
00352      //    << "  recend value = " << recend << endl;
00353     if (direction ==-1) // we are going backwards
00354     {
00355       // backup the file pointer again
00356       lseek(fp,pos,SEEK_SET);
00357       // *(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00358     }
00359     else  // we are going forward
00360     {
00361       // skip over file postion entry in file
00362       lseek(fp,long(sizeof(off_t)),SEEK_CUR);
00363     }
00364   }
00365 }
00366 
00371 void memcpy(const fixed_smartlist & _list,void * p,int nsize)
00372 {
00373   ADUNCONST(fixed_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(list.bptr,p,nsize);
00380   list.bptr+=nsize;
00381 }
00382 
00387 void memcpy(void * p,const fixed_smartlist & _list,int nsize)
00388 {
00389   ADUNCONST(fixed_smartlist,list)
00390   if ( list.bptr+nsize-1 > list.buffend)
00391   {
00392     cerr << " Trying to write outside list buffer" << endl;
00393     exit(1);
00394   }
00395   memcpy(p,list.bptr,nsize);
00396   list.bptr+=nsize;
00397 }
00398 
00399 void fixed_smartlist::operator -= (int n)
00400 {
00401   if (bptr-n<buffer)
00402   {
00403     if (bptr != buffer)
00404     {
00405       cerr << " Sanity error in fixed_smartlist::operator -= (int)" << endl;
00406       exit(1);
00407     }
00408     else
00409     {
00410       // get previous record from the file
00411       read_buffer();
00412       bptr=recend-n+1;
00413     }
00414   }
00415   else
00416   {
00417     bptr-=n;
00418   }
00419 }
00420 void fixed_smartlist::operator -- (void)
00421 {
00422   if (bptr-1<buffer)
00423   {
00424     if (bptr != buffer)
00425     {
00426       cerr << " Sanity error in fixed_smartlist::operator -= (int)" << endl;
00427       exit(1);
00428     }
00429     else
00430     {
00431       // get previous record from the file
00432       read_buffer();
00433       //bptr=recend+1;
00434       bptr=recend;
00435     }
00436   }
00437   else
00438   {
00439     bptr--;
00440   }
00441 }
00442 
00443 void fixed_smartlist::operator += (int nsize)
00444 {
00445   if ( bptr+nsize-1 > buffend)
00446   {
00447     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00448     {
00449       read_buffer();
00450     }
00451     else
00452     {
00453       if ((unsigned int)nsize>bufsize)
00454       {
00455         cout << "Need to increase buffsize in list" << endl;
00456         exit(1);
00457       }
00458       write_buffer();
00459     }
00460   }
00461   else
00462   {
00463     bptr+=nsize;
00464   }
00465 }
00466 
00471 void fixed_smartlist::operator ++ (void)
00472 {
00473   if ( bptr==buffend)
00474   {
00475     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00476     {
00477       read_buffer();
00478     }
00479     else
00480     {
00481       write_buffer();
00482     }
00483   }
00484   else
00485   {
00486     bptr++;
00487   }
00488 }
00489 
00494 void fixed_smartlist::read_file(void)
00495 {
00496   //rewind the file
00497   off_t pos=lseek(fp,0L,SEEK_SET);
00498   int nbytes=0;
00499   char buffer[50000];
00500   int offset=0;
00501   fixed_list_entry * b= (fixed_list_entry*) &(buffer[0]);
00502   cout << b << endl;
00503   int nw=0;
00504   do
00505   {
00506     nw=::read(fp,&nbytes,sizeof(int));
00507     nw=::read(fp,buffer+offset,nbytes);
00508     offset+=nbytes;
00509     ::read(fp,&pos,sizeof(off_t));
00510   }
00511   while(nw);
00512 }