home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 110 / EnigmaAmiga110CD.iso / indispensabili / utility / apdf / xpdf-0.80 / xpdf / mystdio.cc < prev    next >
C/C++ Source or Header  |  1999-06-21  |  5KB  |  239 lines

  1. //========================================================================
  2. //
  3. // mystdio.cc
  4. //
  5. // Copyright 1999 Emmanuel Lesueur
  6. //
  7. //========================================================================
  8.  
  9. #define DB(x) //x
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <stdarg.h>
  14. #include <stdlib.h>
  15. #include <dos/dos.h>
  16. #include <dos/dosextens.h>
  17. #include <dos/dostags.h>
  18. #include <exec/memory.h>
  19. #include <stdarg.h>
  20. #include "mystdio.h"
  21. #include "gmem.h"
  22.  
  23. #ifdef __SASC
  24. #   define throw(x)
  25. #endif
  26.  
  27. #ifdef __PPC__
  28. #   include <powerup/ppcproto/dos.h>
  29. #   include <powerup/gcclib/powerup_protos.h>
  30.  
  31. inline BPTR myOpen(const char* n,LONG m) {
  32.     BPTR r=PPCOpen((char*)n,m);
  33.     DB(printf("Open(%s)=%lx\n",n,r);)
  34.     return r;
  35. }
  36. inline LONG myClose(BPTR f) {
  37.     DB(printf("Close(%lx)\n",f);)
  38.     return PPCClose(f);
  39. }
  40. inline LONG mySeek(BPTR f,LONG b,LONG m) {
  41.     LONG r=PPCSeek(f,b,m);
  42.     DB(printf("Seek(%lx,%ld,%ld)=%ld\n",f,b,m,r);)
  43.     return r;
  44. }
  45. inline LONG myRead(BPTR f,void* b,size_t sz) {
  46.     LONG r=PPCRead(f,b,sz);
  47.     DB(printf("Read(%lx,%p,%u)=%ld\n",f,b,sz,r);)
  48.     return r;
  49. }
  50. #else
  51. #   include <proto/dos.h>
  52.  
  53. inline BPTR myOpen(const char* n,LONG m) {
  54.     return Open((char*)n,m);
  55. }
  56. inline LONG myClose(BPTR f) {
  57.     return Close(f);
  58. }
  59. inline LONG mySeek(BPTR f,LONG o,LONG m) {
  60.     return Seek(f,o,m);
  61. }
  62. inline LONG myRead(BPTR f,void* b,size_t sz) {
  63.     return Read(f,b,sz);
  64. }
  65. #endif
  66.  
  67. size_t myFILE::max_buf;
  68. size_t myFILE::glb_chunk_size;
  69.  
  70. void myFILE::bufsizes(size_t sz1,size_t sz2) {
  71.     if(sz1>1<<20)
  72.     sz1=1<<20;
  73.     else if(sz1==0)
  74.     sz1=1;
  75.     if(sz2>1<<20)
  76.     sz2=1<<20;
  77.     sz1*=1024;
  78.     sz2*=1024;
  79.     if(sz2==0)
  80.     max_buf=0x7fffffff;
  81.     else {
  82.     if(sz1<4096)
  83.         sz1=4096;
  84.     glb_chunk_size=sz1;
  85.     if(sz2<2*sz1)
  86.         sz2=2*sz1;
  87.     max_buf=sz2;
  88.     }
  89. }
  90.  
  91. myFILE::myFILE(const char* name) {
  92.     if(file=myOpen(name,MODE_OLDFILE)) {
  93.     BOOL ok=FALSE;
  94.     if(FileInfoBlock* fib=(FileInfoBlock*)AllocDosObject(DOS_FIB,NULL)) {
  95.         if(ExamineFH(file,fib)) {
  96.         total_size=fib->fib_Size;
  97.         if(total_size<max_buf) {
  98.             chunk_size=total_size;
  99.             max_loaded_chunks=2;
  100.         } else {
  101.             chunk_size=glb_chunk_size;
  102.             max_loaded_chunks=max_buf/chunk_size;
  103.         }
  104.         num_chunks=(total_size+chunk_size-1)/chunk_size;
  105.         chunks=new chunk [num_chunks];
  106.         pos=0;
  107.         last_pos=0;
  108.         num_loaded_chunks=0;
  109.         loaded_chunks=NULL;
  110.         oldest_chunk=NULL;
  111.         ok=TRUE;
  112.         }
  113.         FreeDosObject(DOS_FIB,fib);
  114.     }
  115.     if(ok)
  116.         return;
  117.     }
  118.     throw("");
  119. }
  120.  
  121. myFILE::~myFILE() {
  122.     myClose(file);
  123.     delete [] chunks;
  124. }
  125.  
  126. size_t myFILE::read(void* p,size_t sz) {
  127.     //printf("read(%p,%u)\n",p,sz);
  128.     if(sz>total_size-pos)
  129.     sz=total_size-pos;
  130.     size_t r=sz;
  131.     unsigned n=pos/chunk_size;
  132.     unsigned offs=pos%chunk_size;
  133.     unsigned char* q=static_cast<unsigned char*>(p);
  134.     //bool xx=false;
  135.     while(sz) {
  136.     //printf("sz=%u pos=%u, last_pos=%u, chunk=%u, offs=%u\n",sz,pos,last_pos,n,offs);
  137.     chunk* c=chunks+n;
  138.     size_t sz1=chunk_size;
  139.     if(!c->buf) {
  140.         /*if(!xx) {
  141.         printf("read(%u)\n",sz);
  142.         xx=true;
  143.         }*/
  144.         unsigned char* buf=NULL;
  145.         if(num_loaded_chunks==max_loaded_chunks) {
  146.         buf=oldest_chunk->buf;
  147.         oldest_chunk->buf=NULL;
  148.         oldest_chunk=oldest_chunk->prev;
  149.         oldest_chunk->next=NULL;
  150.         } else {
  151.         ++num_loaded_chunks;
  152.         buf=new unsigned char [chunk_size];
  153.         }
  154.         c->buf=buf;
  155.         c->next=loaded_chunks;
  156.         c->prev=NULL;
  157.         if(loaded_chunks)
  158.         loaded_chunks->prev=c;
  159.         else
  160.         oldest_chunk=c;
  161.         loaded_chunks=c;
  162.         unsigned pos2=n*chunk_size;
  163.         if(last_pos!=pos2)
  164.         mySeek(file,pos2,OFFSET_BEGINNING);
  165.         sz1=myRead(file,buf,chunk_size);/* error handling... */
  166.         if(sz1==-1) {
  167.         r-=sz;
  168.         break;
  169.         }
  170.         last_pos=pos2+sz1;
  171.     } else if(pos-offs+chunk_size>total_size)
  172.         sz1=total_size-pos+offs;
  173.     if(c->prev) {
  174.         c->prev->next=c->next;
  175.         if(c->next)
  176.         c->next->prev=c->prev;
  177.         else {
  178.         oldest_chunk=c->prev;
  179.         oldest_chunk->next=NULL;
  180.         }
  181.         if(loaded_chunks)
  182.         loaded_chunks->prev=c;
  183.         c->next=loaded_chunks;
  184.         c->prev=NULL;
  185.         loaded_chunks=c;
  186.     }
  187.     const unsigned char* s=c->buf+offs;
  188.     if(sz1<=offs) {
  189.         r-=sz;
  190.         break;
  191.     }
  192.     size_t len=sz1-offs;
  193.     size_t sz2=sz<=len?sz:len;
  194.     memcpy(q,s,sz2);
  195.     q+=sz2;
  196.     sz-=sz2;
  197.     pos+=sz2;
  198.     ++n;
  199.     offs=0;
  200.     }
  201.     //printf("->read=%u\n",r);
  202.     return r;
  203. }
  204.  
  205.  
  206. myFILE* myfopen(const char* name,const char* mode) {
  207.     if(*mode=='w')
  208.     throw("invalid open mode.");
  209.     myFILE* f=NULL;
  210.     try {
  211.     f=new myFILE(name);
  212.     }
  213.     catch(...) {
  214.     }
  215.     return f;
  216. }
  217.  
  218. int myFILE::seek(long p,int mode) {
  219.     switch(mode) {
  220.       case SEEK_SET:
  221.     pos=p;
  222.     break;
  223.       case SEEK_CUR:
  224.     pos+=p;
  225.     break;
  226.       case SEEK_END:
  227.     pos=total_size+p;
  228.     break;
  229.       default:
  230.     return -1;
  231.     }
  232.     if(pos>total_size) {
  233.     pos=total_size;
  234.     return -1;
  235.     } else
  236.     return 0;
  237. }
  238.  
  239.