ADMB Documentation  -a65f1c97
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
df1b2f14.cpp
Go to the documentation of this file.
1 /*
2  * $Id$
3  *
4  * Author: David Fournier
5  * Copyright (c) 2008-2012 Regents of the University of California
6  */
11 #include <df1b2fun.h>
12 #include <cassert>
13 
14 #ifdef _MSC_VER
15  #ifdef _M_X64
16  typedef __int64 ssize_t;
17  #else
18  typedef int ssize_t;
19  #endif
20 #else
21  #include <unistd.h>
22 #endif
23 
28  endof_file_ptr(-1),
29  doubleptr(NULL),
30  recend(NULL),
31  sbptr(NULL),
32  fp(-1)
33 {
34  nentries=0;
35  end_saved=0;
36  eof_flag=0;
37  noreadflag=0;
38  written_flag=0;
39  direction=0;
40  bufsize=0;
41  true_buffer=0;
42  true_buffend=0;
43  buffer=0;
44  buffend=0;
45  bptr=buffer;
46 }
50 fixed_smartlist2::fixed_smartlist2(const size_t _bufsize,
51  const adstring& _filename):
52  endof_file_ptr(-1),
53  recend(NULL),
54  sbptr(NULL)
55 {
56  allocate(_bufsize,_filename);
57 }
58 
63 void fixed_smartlist2::allocate(const size_t _bufsize,
64  const adstring& _filename)
65 {
66  nentries=_bufsize/sizeof(int);
67  end_saved=0;
68  eof_flag=0;
69  noreadflag=0;
70  written_flag=0;
71  direction=0;
72  bufsize=_bufsize;
73  filename=_filename;
75  doubleptr=(double*)true_buffer;
79  bptr=buffer;
80  *true_buffer=5678;
81  *true_buffend=9999;
82 #ifdef _MSC_VER
83  fp=open((char*)(filename), O_RDWR | O_CREAT | O_TRUNC |
84  O_BINARY, S_IWRITE | S_IREAD);
85 #else
86  fp=open((char*)(filename), O_RDWR | O_CREAT | O_TRUNC |
87  O_BINARY, S_IRUSR | S_IWUSR);
88 #endif
89  if (fp < 0)
90  {
91  cerr << "Error trying to open file " << filename
92  << " in class fixed_smartlist2 " << endl;
93  ad_exit(1);
94  }
95  else
96  {
97  /*off_t pos=*/lseek(fp, 0L, SEEK_CUR);
98  }
99 }
100 
104 void fixed_smartlist2::write(const size_t n)
105 {
106 #if defined(__MINGW64__) || (defined(_WIN64) && defined(_MSC_VER))
107  assert(n <= INT_MAX);
108  ssize_t nw = ::write(fp, buffer, (int)n);
109 #else
110  ssize_t nw = ::write(fp, buffer, n);
111 #endif
112  if (nw <= -1 || (size_t)nw != n)
113  {
114  cerr << "Error writing to file " << filename << endl;
115  ad_exit(1);
116  }
117 }
118 
123 {
124  bptr=buffer;
125  eof_flag=0;
126  if (written_flag)
127  {
128  lseek(fp,0L,SEEK_SET);
129  // get the record size
130  unsigned int nbytes = 0;
131  ssize_t ret = ::read(fp,&nbytes,sizeof(unsigned int));
132  assert(ret != -1);
133  if (nbytes > bufsize)
134  {
135  cerr << "Error -- record size in file seems to be larger than"
136  " the buffer it was created from " << endl
137  << " buffer size is " << bufsize << " record size is supposedly "
138  << nbytes << endl;
139  ad_exit(1);
140  }
141  // now read the record into the buffer
142  ret = ::read(fp,buffer,nbytes);
143  assert(ret != -1);
144  //cout << "Number of bytes read " << nr << endl;
145  // skip over file postion entry in file
146  // so we are ready to read second record
147  lseek(fp,(off_t)sizeof(off_t),SEEK_CUR);
148  }
149 }
150 
156 {
157  end_saved=0;
158  eof_flag=0;
159  bptr=buffer;
160  //int nbytes=0;
161  written_flag=0;
162  lseek(fp,0L,SEEK_SET);
163  set_forward();
164 }
165 
170 void fixed_smartlist2::check_buffer_size(const size_t nsize)
171 {
172  if ( bptr+nsize-1 > buffend)
173  {
175  {
176  read_buffer();
177  }
178  else
179  {
180  if (nsize>bufsize)
181  {
182  cout << "Need to increase buffsize in list" << endl;
183  ad_exit(1);
184  }
185  write_buffer();
186  }
187  }
188 }
193 {
194  if (written_flag)
195  {
196  if (end_saved)
197  {
198 #ifdef OPT_LIB
199  lseek(fp, endof_file_ptr, SEEK_SET);
200 #else
201  off_t ret = lseek(fp, endof_file_ptr, SEEK_SET);
202  assert(ret >= 0);
203 #endif
204  read_buffer();
205  set_recend();
206  }
207  }
208 }
209 
215 {
216  if (written_flag)
217  {
218  if (!end_saved)
219  {
221  end_saved=1;
222  }
223  }
224 }
225 
231 {
232  int _nbytes=adptr_diff(bptr,buffer);
233  if (_nbytes > 0)
234  {
235  unsigned int nbytes = (unsigned int)_nbytes;
236 
237  written_flag=1;
238  // get the current file position
239  off_t pos=lseek(fp,0L,SEEK_CUR);
240 
241  // write the size of the next record into the file
242  ssize_t ret = ::write(fp,&nbytes,sizeof(unsigned int));
243  assert(ret != -1);
244 
245  // write the record into the file
246  ssize_t nw = ::write(fp,buffer,nbytes);
247  if (nw < _nbytes)
248  {
249  cerr << "Error writing to file " << filename << endl;
250  ad_exit(1);
251  }
252  // reset the pointer to the beginning of the buffer
253  bptr=buffer;
254 
255  // now write the previous file position into the file so we can back up
256  // when we want to.
257  ret = ::write(fp,&pos,sizeof(off_t));
258  assert(ret != -1);
259 
260  endof_file_ptr=lseek(fp,0L,SEEK_CUR);
261 
262  //cout << lseek(fp,0L,SEEK_CUR) << endl;
263  }
264 }
265 
271 {
272  int _nbytes=adptr_diff(bptr+1,buffer);
273  if (_nbytes > 0)
274  {
275  unsigned int nbytes = (unsigned int)_nbytes;
276 
277  written_flag=1;
278  // get the current file position
279  off_t pos=lseek(fp,0L,SEEK_CUR);
280 
281  // write the size of the next record into the file
282  ssize_t ret = ::write(fp, &nbytes, sizeof(unsigned int));
283  assert(ret != -1);
284 
285  // write the record into the file
286  ret = ::write(fp,buffer,nbytes);
287  assert(ret != -1);
288  if (ret < _nbytes)
289  {
290  cerr << "Error writing to file " << filename << endl;
291  ad_exit(1);
292  }
293  // reset the pointer to the beginning of the buffer
294  bptr=buffer;
295 
296  // now write the previous file position into the file so we can back up
297  // when we want to.
298  ret = ::write(fp,&pos,sizeof(off_t));
299  assert(ret != -1);
300 
301  endof_file_ptr=lseek(fp,0L,SEEK_CUR);
302 
303  //cout << lseek(fp,0L,SEEK_CUR) << endl;
304  }
305 }
306 
311 {
312  if (!written_flag)
313  {
314  if (direction ==-1)
315  eof_flag=-1;
316  else
317  eof_flag=1;
318  }
319  else
320  {
321  off_t pos = 0;
322  if (direction ==-1) // we are going backwards
323  {
324  off_t ipos=lseek(fp,0L,SEEK_CUR);
325  if (ipos ==0)
326  {
327  eof_flag=-1;
328  return;
329  }
330  // offset of the begining of the record is at the end
331  // of the record
332 #ifdef OPT_LIB
333  lseek(fp,-((off_t)sizeof(off_t)),SEEK_CUR);
334 #else
335  off_t ret2 = lseek(fp,-((off_t)sizeof(off_t)),SEEK_CUR);
336  assert(ret2 >= 0);
337 #endif
338  ssize_t ret = read(fp,&pos,sizeof(off_t));
339  assert(ret != -1);
340 
341  // back up to the beginning of the record (plus record size)
342 #ifdef OPT_LIB
343  lseek(fp,pos,SEEK_SET);
344 #else
345  ret2 = lseek(fp,pos,SEEK_SET);
346  assert(ret2 >= 0);
347 #endif
348  //*(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
349  }
350  // get the record size
351  int _nbytes = 0;
352  ssize_t result = ::read(fp,&_nbytes,sizeof(int));
353  assert(result != -1);
354  if (_nbytes > 0)
355  {
356  const size_t nbytes = (size_t)_nbytes;
357  if (nbytes > bufsize)
358  {
359  cerr << "Error -- record size in file seems to be larger than"
360  " the buffer it was created from " << endl
361  << " buffer size is " << bufsize << " record size is supposedly "
362  << nbytes << endl;
363  ad_exit(1);
364  }
365  // now read the record into the buffer
366 #if defined(__MINGW64__) || (defined(_WIN64) && defined(_MSC_VER))
367  ssize_t nr = ::read(fp,buffer,_nbytes);
368 #else
369  ssize_t nr = ::read(fp,buffer,nbytes);
370 #endif
371  assert(nr != -1);
372  if (nr != _nbytes)
373  {
374  cerr << "Error: read only " << nr << " of " << nbytes << "bytes.\n";
375  ad_exit(1);
376  }
377  // reset the pointer to the beginning of the buffer
378  bptr=buffer;
379  size_t ns = nbytes / sizeof(int);
380  recend=bptr+ns-1;
381  //cout << "Number of bytes read " << nr
382  // << " recend value = " << recend << endl;
383  if (direction ==-1) // we are going backwards
384  {
385  // backup the file pointer again
386 #ifdef OPT_LIB
387  lseek(fp,pos,SEEK_SET);
388 #else
389  off_t ret = lseek(fp,pos,SEEK_SET);
390  assert(ret >= 0);
391 #endif
392  // *(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
393  }
394  else // we are going forward
395  {
396  //\todo need test
397 
398  // skip over file postion entry in file
399 #ifdef OPT_LIB
400  lseek(fp, (off_t)sizeof(off_t), SEEK_CUR);
401 #else
402  off_t ret = lseek(fp, (off_t)sizeof(off_t), SEEK_CUR);
403  assert(ret >= 0);
404 #endif
405  }
406  }
407  }
408 }
409 
414 void memcpy(const fixed_smartlist2 & _list,void * p, const size_t nsize)
415 {
417  if ( list.bptr+nsize-1 > list.buffend)
418  {
419  cerr << " Trying to write outside list buffer" << endl;
420  ad_exit(1);
421  }
422  memcpy(list.bptr,p,nsize);
423  list.bptr+=nsize;
424 }
425 
430 void memcpy(void * p,const fixed_smartlist2 & _list, const size_t nsize)
431 {
433  if ( list.bptr+nsize-1 > list.buffend)
434  {
435  cerr << " Trying to write outside list buffer" << endl;
436  ad_exit(1);
437  }
438  memcpy(p,list.bptr,nsize);
439  list.bptr+=nsize;
440 }
441 
447 {
448  if (bptr-n<buffer)
449  {
450  if (bptr != buffer)
451  {
452  cerr << " Sanity error in fixed_smartlist2::operator -= (int)" << endl;
453  ad_exit(1);
454  }
455  else
456  {
457  // get previous record from the file
458  read_buffer();
459  bptr=recend-n+1;
460  }
461  }
462  else
463  {
464  bptr-=n;
465  }
466 }
467 
473 {
474  if (bptr-1<buffer)
475  {
476  if (bptr != buffer)
477  {
478  cerr << " Sanity error in fixed_smartlist2::operator -= (int)" << endl;
479  ad_exit(1);
480  }
481  else
482  {
483  // get previous record from the file
484  read_buffer();
485  //bptr=recend+1;
486  bptr=recend;
487  }
488  }
489  else
490  {
491  bptr--;
492  }
493 }
494 
500 {
501  if ( bptr+nsize-1 > buffend)
502  {
504  {
505  read_buffer();
506  }
507  else
508  {
509  if ((unsigned int)nsize>bufsize)
510  {
511  cout << "Need to increase buffsize in list" << endl;
512  ad_exit(1);
513  }
514  write_buffer();
515  }
516  }
517  else
518  {
519  bptr+=nsize;
520  }
521 }
522 
528 {
529  if ( bptr==buffend)
530  {
532  {
533  read_buffer();
534  }
535  else
536  {
537  write_buffer();
538  }
539  }
540  else
541  {
542  bptr++;
543  }
544 }
545 
550 {
551  //rewind the file
552  off_t pos=lseek(fp,0L,SEEK_SET);
553  char buffer[50000];
554  int offset=0;
555  fixed_list_entry * b= (fixed_list_entry*) &(buffer[0]);
556  cout << b << endl;
557  ssize_t nw = 0;
558  do
559  {
560  int nbytes = 0;
561  nw = ::read(fp,&nbytes,sizeof(int));
562  if (nw != -1)
563  {
564  nw = ::read(fp, buffer + offset, (size_t)nbytes);
565  if (nw != -1)
566  {
567  offset+=nbytes;
568  nw = ::read(fp,&pos,sizeof(off_t));
569  }
570  }
571  }
572  while(nw);
573 }
void set_recend()
Definition: df1b2fun.h:699
void read(const test_smartlist &, void *, int nsize)
void initialize(void)
Description not yet available.
Definition: df1b2f14.cpp:155
void write_buffer(void)
Description not yet available.
Definition: df1b2f14.cpp:270
void memcpy(test_smartlist &dest, void *source, const size_t nsize)
memcpy for test_smartlist
Definition: df1b2f10.cpp:367
void write_buffer_one_less(void)
Description not yet available.
Definition: df1b2f14.cpp:230
void read_file(void)
Definition: df1b2f14.cpp:549
fixed_smartlist2(void)
Default constructor.
Definition: df1b2f14.cpp:27
void operator++(void)
Description not yet available.
Definition: df1b2f14.cpp:527
#define ADUNCONST(type, obj)
Creates a shallow copy of obj that is not CONST.
Definition: fvar.hpp:140
void operator-=(int)
Description not yet available.
Definition: df1b2f14.cpp:446
int adptr_diff(void *x, void *y)
Definition: df1b2fn2.cpp:110
void allocate(const size_t bufsize, const adstring &filename)
Description not yet available.
Definition: df1b2f14.cpp:63
exitptr ad_exit
Definition: gradstrc.cpp:53
#define AD_ALLOCATE(ptr, type, n, classname)
Definition: df1b2fun.h:179
void save_end(void)
Description not yet available.
Definition: df1b2f14.cpp:214
Description not yet available.
Definition: df1b2fun.h:745
int * true_buffend
Definition: df1b2fun.h:689
size_t nentries
Definition: df1b2fun.h:678
void rewind(void)
Definition: df1b2f14.cpp:122
Description not yet available.
Definition: df1b2fun.h:669
void operator--(void)
Description not yet available.
Definition: df1b2f14.cpp:472
prnstream & endl(prnstream &)
void restore_end(void)
Set to end of file ptr.
Definition: df1b2f14.cpp:192
void set_forward(void)
Definition: df1b2fun.h:712
#define O_BINARY
Definition: fvar.hpp:163
double * doubleptr
Definition: df1b2fun.h:687
int * true_buffer
Definition: df1b2fun.h:688
void operator+=(int)
Description not yet available.
Definition: df1b2f14.cpp:499
static int get_passnumber(void)
Definition: df1b2fun.h:296
size_t pos(const adstring &substr, const adstring &s)
Definition: string3.cpp:56
Description not yet available.
Definition: df1b2fun.h:591
Description not yet available.
void write(const size_t n)
Definition: df1b2f14.cpp:104
void read_buffer(void)
Read buffer.
Definition: df1b2f14.cpp:310
adstring filename
Definition: df1b2fun.h:696
void check_buffer_size(const size_t)
Description not yet available.
Definition: df1b2f14.cpp:170
off_t endof_file_ptr
Definition: df1b2fun.h:680
size_t bufsize
Definition: df1b2fun.h:695