ODIO.H
上传用户:hell82222
上传日期:2013-12-19
资源大小:1872k
文件大小:15k
源码类别:

CAD

开发平台:

Visual C++

  1. /* #define OD_GENERIC_READ */
  2. /* #define OD_FAST_READ */
  3. /* one or the other of the above must be defined */
  4. #ifdef _cplusplus
  5.   extern "C" {
  6. #endif
  7. double od_atof(char *string)
  8. {
  9.   return atof(string);
  10. }
  11. /* odio functions */
  12. /* write functions */
  13. int odiow_fclose(void *f)
  14. {
  15.   return(fclose((FILE *)f));
  16. }
  17. void *odiow_fopen (void *path,char *accessmodes)
  18. {
  19.   FILE *tfile;
  20.   if ((tfile=fopen((char*)path,accessmodes))==NULL) return(NULL);
  21. /* setvbuf should increase performance somewhat */
  22. #ifndef ODA_WINCE
  23.   setvbuf(tfile,NULL,_IOFBF,8192);
  24. #endif 
  25.   return(tfile);
  26. }
  27. int odiow_fputs(const char *str,void *f)
  28. {
  29.   return(fputs(str,(FILE *)f));
  30. }
  31. int odiow_fread (void *buf, unsigned int size, unsigned int num, void *f)
  32. {
  33.   return(fread(buf,size,num,(FILE *)f));
  34. }
  35. int odiow_fseek (void *f, OdaLong offset, int whence)
  36. {
  37.   return(fseek((FILE *)f,offset,whence));
  38. }
  39. OdaLong odiow_ftell(void *f)
  40. {
  41.   return(ftell((FILE *)f));
  42. }
  43. int odiow_fwrite(void *b,int size,int count, void *f)
  44. {
  45.   return(fwrite(b,size,count,(FILE *)f));
  46. }
  47. #ifdef OD_GENERIC_READ
  48. /* read functions */
  49. int odior_fclose(void *f)
  50. {
  51.   return(fclose((FILE *)f));
  52. }
  53. short odior_feof(void *f)
  54. {
  55.   return(feof((FILE *)f));
  56. }
  57. unsigned char odior_fgetc(void *f)
  58. {
  59.   return(getc((FILE *)f));
  60. }
  61. #define OD_CR 13
  62. #define OD_LF 10
  63. char *odior_fgetdxfline(char *s, unsigned int n, void *f2)
  64. {
  65.   char lastchar=0;
  66.   int onemorech;
  67.   FILE *f=(FILE *)f2;
  68.   char *origs=s;
  69.   if (!n || feof(f)) return(NULL);
  70.   while (n && lastchar!=OD_CR && lastchar!=OD_LF && !feof(f)) {
  71.     *s++ = lastchar = getc(f);
  72.     n--;
  73.   }
  74.   if (feof(f) || n==0) s--;
  75.   *s=0;
  76. /* we stopped on either r or n (or feof); we read one more
  77.    character if it was r and not eof to determine whether we had a cr/lf
  78.    pair.  If we didn't, put the character back.  This fixes MAC text files
  79.    which end in cr only */
  80.   if (lastchar==OD_CR && !feof(f)) {
  81.     onemorech=getc(f);
  82.     if (!feof(f))  /* not really eof yet, next one is */
  83.       if (onemorech!=OD_LF) ungetc(onemorech,f);
  84.   }
  85. /* added this to deal with the absurd case of lines terminated with nr */
  86.   else if (lastchar==OD_LF && !feof(f)) {
  87.     onemorech=getc(f);
  88.     if (!feof(f))  /* not really eof yet, next one is */
  89.       if (onemorech!=OD_CR) ungetc(onemorech,f);
  90.   }
  91.   return(origs);
  92. }
  93. OdaLong odior_flength(void *f2)   /* a dumb, but generic way to do this */
  94. {                              /* depending on your platform, fstat may */
  95.   FILE *f=(FILE *)f2;          /* be a better choice.  We have had some */
  96.   OdaLong curloc,filelen;         /* trouble with it on Win95 networks, however */
  97.   curloc=ftell(f);             /* hold location */
  98.   fseek(f,0L,2);               /* seek to end */
  99.   filelen=ftell(f);            /* get location, which is file size */
  100.   fseek(f,curloc,0);           /* restore position */
  101.   return(filelen);             /* return size */
  102. }
  103. void *odior_fopen (void *path)
  104. {
  105.   FILE *tfile;
  106.   if ((tfile=fopen((char*)path,"rb"/*DNT*/))==NULL) return(NULL);
  107. #ifndef ODA_WINCE
  108.   setvbuf(tfile,NULL,_IOFBF,8192);
  109. #endif //ODA_WINCE
  110.   return(tfile);
  111. }
  112. int odior_fread (void *buf, unsigned int size, unsigned int num, void *f)
  113. {
  114.   return(fread(buf,size,num,(FILE *)f));
  115. }
  116. int odior_fseek (void *f, OdaLong offset, int whence)
  117. {
  118.   return(fseek((FILE *)f,offset,whence));
  119. }
  120. OdaLong odior_ftell(void *f)
  121. {
  122.   return(ftell((FILE *)f));
  123. }
  124. #endif
  125. #ifdef OD_FAST_READ
  126. /* This is a set of optimized read routines which does least-recently-used
  127.    buffering of the file data, allowing for frequently accessed data to be
  128.    kept available.  They also use low level file I/O (open, read, close),
  129.    rather than the high level routines (fopen, etc.) for increased
  130.    performance.  Our experience shows approximately a 3x increase in speed
  131.    when these routines (or derivatives of them) are used.
  132.    The downside is that these routines are not completely portable, although
  133.    with minor changes they will run on UNIX platforms.  We may implement an
  134.    OD_FAST_READ_UNIX #define which will handle those platforms in the future.
  135.    The same types of operations shown here are also portable to Macintosh.
  136. */
  137. #include <io.h>
  138. #define READFLAGS  (O_RDONLY | O_BINARY)
  139. #define WRITEFLAGS (O_WRONLY | O_BINARY)
  140. #define MAXODIOBLOCKS 16
  141. /* this version uses the critical error handlers in the
  142.    example programs */
  143. extern short criterrhandler(short num);
  144. #ifndef ODIOFILESTRUDEFINED
  145. struct odioblockstru {
  146.   char *buf;        /* this buffer */
  147.   OdaLong  startaddr;  /* address from which it came in the file */
  148.   short validbytes; /* number of valid bytes it holds */
  149.   OdaLong  lru;        /* least recently used counter */
  150. } ;
  151. typedef struct ODIO_FILESTRU {
  152.   OdaLong physfilepos;        /* where the file pointer is */
  153.   OdaLong bufpos;             /* position from which buf was filled */
  154.   int handle;              /* file handle */
  155.   int lvl;                 /* bytes left in buf */
  156.   unsigned short bufbytes; /* valid bytes read into buffer */
  157.   char *nexchptr;          /* pointer to next char in buffer */
  158.   char *cbuf;              /* pointer to the buffer currently being used */
  159.   short eofflag;           /* 1 if filbuf fails */
  160.   short usingblock;        /* which block is currently in use */
  161.   struct odioblockstru datablock[MAXODIOBLOCKS];  /* the data being held */
  162. } ODIO_FILE;
  163. #define ODIOFILESTRUDEFINED
  164. #endif
  165. short odioreadbufs=min(8,MAXODIOBLOCKS);   /* number of read buffers */
  166. short odioblocksize=8192;                  /* size of each read buffer */
  167. OdaLong  odiopositionmask=~(8192-1);          /* mask to allow position check */
  168. /* a full implementation should probably reset odiolru to 0L every
  169.    time adInitAd2() is called. */
  170. OdaLong  odiolru=0L;                          /* counter to track use of blocks */
  171. void odior_filbuf _((ODIO_FILE *f));
  172. unsigned char odior_fgetc _((void *f));
  173. void *odior_fopen _((void *path));
  174. int odior_fclose _((void *f));
  175. int odior_fseek _((void *f, OdaLong offset, int whence));
  176. int odior_fread _((void *buf, unsigned int size, unsigned int num, void *f));
  177. char *odior_fgetdxfline _((char *s, unsigned int n, void *f));
  178. OdaLong odior_ftell _((void *f));
  179. #define odior_getc(f) 
  180.   ((f)->datablock[(f)->usingblock].lru=odiolru++, 
  181.   (--((f)->lvl) >= 0) ? (*(f)->nexchptr++) : 
  182.      odior_fgetc(f))
  183. OdaLong odior_ftell(void *f2)
  184. {
  185.   ODIO_FILE *f=(ODIO_FILE *)f2;
  186.   return(f->bufpos + (f->nexchptr - f->cbuf));
  187. }
  188. unsigned char odior_fgetc(void *f2)
  189. {
  190.   ODIO_FILE *f=(ODIO_FILE *)f2;
  191.   OdaLong origbufpos;
  192.   f->datablock[f->usingblock].lru=odiolru++;
  193.   if ((f->lvl)<=0) {
  194.     origbufpos=f->bufpos;
  195.     f->bufpos+=f->bufbytes;
  196.     odior_filbuf(f);
  197. /* this is to catch the situation where AD is already holding the block
  198.    in which this buffer is being held (so filbuf just sets it up and
  199.    comes back), but obviously we are trying to read past where we were
  200.    in the buffer, which means that the file is truncated */
  201.     if (f->bufpos==origbufpos) {
  202.       f->eofflag=1;
  203.       return(0);
  204.     }
  205.   }
  206.   f->lvl--;
  207.   return(*f->nexchptr++);
  208. }
  209. short odior_feof(void *f)
  210. {
  211.   return(((ODIO_FILE *)f)->eofflag);
  212. }
  213. int odior_ungetc(int ch,void *f2)
  214. {
  215.   ODIO_FILE *f=(ODIO_FILE *)f2;
  216.   f->nexchptr--;
  217.   f->lvl++;
  218.   f->eofflag=0;
  219.   *(f)->nexchptr = ch;
  220.   return(1);
  221. }
  222. #define OD_CR 13
  223. #define OD_LF 10
  224. char *odior_fgetdxfline(char *s, unsigned int n, void *f2)
  225. {
  226.   ODIO_FILE *f=(ODIO_FILE *)f2;
  227.   char lastchar=0,onemorech;
  228.   if (!n || odior_feof(f)) return(NULL);
  229.   f->datablock[f->usingblock].lru=odiolru++;
  230.   while (n && lastchar!=OD_CR && lastchar!=OD_LF && !odior_feof(f)) {
  231.     *s++ = lastchar =
  232. /* this is odior_getc, without the lru increment */
  233.        (--((f)->lvl) >= 0) ? (*(f)->nexchptr++) : odior_fgetc(f);
  234.     n--;
  235.   }
  236.   if (odior_feof(f) || n==0) s--;
  237.   *s=0;
  238. /* we stopped on either r or n (or feof); we read one more
  239.    character if it was r and not eof to determine whether we had a cr/lf
  240.    pair.  If we didn't, put the character back.  This fixes MAC text files
  241.    which end in cr only */
  242.   if (lastchar==OD_CR && !odior_feof(f)) {
  243.     onemorech=odior_getc(f);
  244.     if (odior_feof(f)) f->eofflag=0;  /* not really eof yet, next one is */
  245.     else if (onemorech!=OD_LF) odior_ungetc(onemorech,f);
  246.   }
  247. /* added this to deal with the absurd case of lines terminated with nr */
  248.   else if (lastchar==OD_LF && !odior_feof(f)) {
  249.     onemorech=odior_getc(f);
  250.     if (odior_feof(f)) f->eofflag=0;  /* not really eof yet, next one is */
  251.     else if (onemorech!=OD_CR) odior_ungetc(onemorech,f);
  252.   }
  253.   return(s);
  254. }
  255. int odior_fseek(void *f2, OdaLong offset, int whence)
  256. {
  257.   ODIO_FILE *f=(ODIO_FILE *)f2;
  258.   unsigned short bytestoadvance;
  259.   if (whence==1) {  /* change it to 0 -- note, whence==2 not supported */
  260.     offset+=(f->bufpos+(f->nexchptr - f->cbuf));
  261.   }
  262. /* from here on assume whence is 0 */
  263. /* moved eof set up here -- if filbuf hits eof, it hits eof */
  264.   f->eofflag=0;
  265. /* if it's not in the area we're holding, seek to it */
  266.   if (offset < f->bufpos || offset >= f->bufpos + (OdaLong)f->bufbytes) {
  267.     f->bufpos=offset & odiopositionmask;
  268.     odior_filbuf(f);  /* locates it if we're already holding in another block */
  269.   }
  270.   f->nexchptr=(char *)(f->cbuf + (bytestoadvance=(unsigned short)(offset - f->bufpos)));
  271.   f->lvl = f->bufbytes - bytestoadvance;
  272.   return(0);
  273. }
  274. int odior_fread(void *bufvoid, unsigned int size, unsigned int num, void *f2)
  275. /* this assumes we will always find enough data to satisfy the request */
  276. {
  277.   ODIO_FILE *f=(ODIO_FILE *)f2;
  278.   OdaLong bytesleft;
  279.   unsigned short bytestoread;
  280.   unsigned char *buf=(unsigned char *)bufvoid;
  281.   f->datablock[f->usingblock].lru=odiolru++;
  282.   bytesleft=(OdaLong)size*(OdaLong)num;
  283.   while (bytesleft > 0L && !odior_feof(f)) {
  284.     if (f->lvl <= 0) {
  285.       f->bufpos+=f->bufbytes;
  286.       odior_filbuf(f);  /* get something in here */
  287.     }
  288.     if ((OdaLong)f->lvl<bytesleft) bytestoread=(unsigned short)f->lvl;
  289.     else bytestoread=(unsigned short)bytesleft;
  290.     memcpy(buf,f->nexchptr,bytestoread);
  291.     f->lvl -= bytestoread;
  292.     f->nexchptr += bytestoread;
  293.     buf += bytestoread;
  294.     bytesleft -= bytestoread;
  295.   }
  296.   return(num);
  297. }
  298. void *odior_fopen(void *path)
  299. {
  300.   ODIO_FILE *f;
  301.   short i;
  302.   if ((f=(ODIO_FILE *)odmem_malloc(sizeof(ODIO_FILE)))==NULL) return(NULL);
  303.   if ((f->handle=open((const char*)path,READFLAGS))==-1) {
  304.     odmem_free(f);
  305.     return(NULL);
  306.   }
  307.   f->eofflag=f->bufbytes=f->lvl=0;
  308.   f->bufpos=0L;  /* to start reads from 0L */
  309.   f->cbuf=NULL;
  310.   f->nexchptr=(char *)f->cbuf;
  311.   f->usingblock = -1;
  312.   f->physfilepos=0L;
  313.   for (i=0; i<odioreadbufs; i++)
  314.     f->datablock[i].buf=NULL;
  315.   for (i=0; i<odioreadbufs; i++) {
  316.     if ((f->datablock[i].buf=(char *)odmem_malloc(odioblocksize))==NULL) {
  317.       odior_fclose(f);
  318.       criterrhandler(AD_CRITERR_MALLOCERROR);
  319.     }
  320.     f->datablock[i].validbytes=0;
  321.     f->datablock[i].lru = -1L;
  322.     f->datablock[i].startaddr = -1L;
  323.   }
  324.   odior_fseek(f,0L,0);  /* initial seek, gets a buffer & stuff */
  325.   if (f->eofflag) {   /* file is empty */
  326.     odior_fclose(f);
  327.     return(NULL);
  328.   }
  329.   return(f);
  330. }
  331. int odior_fclose(void *f2)
  332. {
  333.   ODIO_FILE *f=(ODIO_FILE *)f2;
  334.   short retval,i;
  335. /* indicate buffers no longer in use */
  336.   for (i=0; i<odioreadbufs; i++) {
  337.     if (f->datablock[i].buf!=NULL) odmem_free(f->datablock[i].buf);
  338.     f->datablock[i].lru = -1L;
  339.     f->datablock[i].validbytes=0;
  340.     f->datablock[i].startaddr = -1L;
  341.   }
  342.   retval=close(f->handle);
  343.   odmem_free(f);
  344.   return(retval);
  345. }
  346. OdaLong odior_flength(void *f)
  347. {
  348.   return(_filelength(((ODIO_FILE *)f)->handle));
  349. }
  350. void odior_filbuf(ODIO_FILE *f)
  351. {
  352.   short i,minindex;
  353.   OdaLong minlru;
  354.   struct odioblockstru *minptr;
  355.   char readerror;
  356. /*
  357. printf("in filbuf, this is the buffer hold address array:n");
  358. for (i=0; i<odioreadbufs; i++)
  359.   printf("%d: %ldn",i,f->datablock[i].startaddr);
  360. */
  361.   f->usingblock = -1;
  362. /* see if we are holding it already */
  363.   for (i=0; i<odioreadbufs; i++) {
  364.     if (f->datablock[i].startaddr==f->bufpos)
  365.   break;
  366.   }
  367.   if (i<odioreadbufs) {   /* we are already holding this part of the file */
  368.     f->cbuf=f->datablock[i].buf;
  369.     f->bufpos=f->datablock[i].startaddr;
  370.     f->lvl=f->bufbytes=f->datablock[i].validbytes;
  371.     if (f->lvl==0) f->eofflag=1;
  372.     else f->eofflag=0;
  373.     f->nexchptr=(char *)f->cbuf;
  374.     f->datablock[i].lru=odiolru++;
  375.     f->usingblock=i;
  376.     return;
  377.   }
  378. /* not holding it, so look for a buffer to read into */
  379. /* first see if any are not yet loaded */
  380.   minptr=NULL;
  381.   minindex=0;
  382.   for (i=0; i<odioreadbufs; i++) {
  383.     if (f->datablock[i].startaddr==-1L) {
  384.       minindex=i;
  385.       minptr=&f->datablock[i];
  386.       break;
  387.     }
  388.   }
  389. /* if all were used, then look for the least recently used one */
  390.   if (minptr==NULL) {
  391.     minlru=0x7FFFFFFF;
  392.     minptr=NULL;
  393.     minindex=0;
  394.     for (i=0; i<odioreadbufs; i++) {
  395.       if (f->datablock[i].lru<0L) f->datablock[i].lru=0L;
  396.       if (f->datablock[i].lru<minlru) {
  397.         minlru=f->datablock[i].lru;
  398.         minptr=&f->datablock[i];
  399.         minindex=i;
  400.       }
  401.     }
  402.   }
  403.   if (minptr==NULL) return;  /* couldn't find one */
  404. /* if we are not already physically at the read location, move there */
  405. /* then read into the buffer */
  406.   readerror=0;
  407.   do {
  408.     if (f->physfilepos!=f->bufpos || readerror) {
  409.       lseek(f->handle,f->bufpos,0);
  410.     }
  411.     readerror=0;
  412.     minptr->validbytes=read(f->handle,minptr->buf,odioblocksize);
  413. /* check for error */
  414.     if (minptr->validbytes==-1) readerror=1;
  415.     if (readerror) criterrhandler(AD_CRITERR_FILEREADERROR);
  416.   } while (readerror);
  417.   f->physfilepos=f->bufpos+minptr->validbytes;
  418.   minptr->startaddr=f->bufpos;
  419.   minptr->lru=odiolru++;
  420.   f->bufbytes = f->lvl = minptr->validbytes;
  421.   f->cbuf=minptr->buf;
  422.   if (f->lvl==0) f->eofflag=1;
  423.   else f->eofflag=0;
  424.   f->nexchptr=(char *)f->cbuf;
  425.   f->usingblock=minindex;
  426. }
  427. #endif
  428. int odior_access(void *path, int mode)
  429. {
  430. #ifdef ODA_WINCE
  431. #pragma message ("Warning: access method needs to be implemented!")
  432. return 0;
  433. #else
  434. return access((const char *)path, mode);
  435. #endif
  436. }
  437. #ifndef _CRTDBG_MAP_ALLOC
  438. void *odmem_malloc(int size)
  439. {
  440.   return(malloc(size));
  441. }
  442. void odmem_free(void *loc)
  443. {
  444.   free(loc);
  445. }
  446. #endif /* _CRTDBG_MAP_ALLOC */
  447. short odvm_init(void)
  448. {
  449.   return(1);
  450. }
  451. short odvm_term (void)
  452. {
  453.   return(1);
  454. }
  455. short odvm_readbytes(char *ptr,AD_VMADDR vmloc,unsigned short bytes)
  456. {
  457.   memcpy(ptr,vmloc,bytes);
  458.   return(1);
  459. }
  460. short odvm_writebytes(AD_VMADDR vmloc,char *ptr,unsigned short bytes)
  461. {
  462.   memcpy(vmloc,ptr,bytes);
  463.   return(1);
  464. }
  465. short odvm_free(AD_VMADDR ptr)
  466. {
  467.   free(ptr);
  468.   return(1);
  469. }
  470. AD_VMADDR odvm_malloc(unsigned num_bytes)
  471. {
  472.   return((AD_VMADDR)malloc(num_bytes));
  473. }
  474. #ifdef _cplusplus
  475.   }
  476. #endif