home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_C / SNIP9404.ZIP / HUGEREAD.C < prev    next >
C/C++ Source or Header  |  1994-04-03  |  6KB  |  243 lines

  1. /*
  2. **  HUGEREAD.C - "Universal" PC read and write functions using huge data
  3. **               and far pointers.
  4. **
  5. **  NOTES:
  6. **
  7. **  1. If these functions are called with a prototype in scope, passed
  8. **     parameters will be coerced to the proper data types.
  9. **
  10. **  2. Since these call read() and write(), all normal mode flags which
  11. **     are supported by individual compilers will be honored.
  12. **
  13. **  3. In small data memory models (S, T, and M), an intermediate buffer
  14. **     is allocated and used. In large data models (L and C), the data
  15. **     are read/written directly from/to target memory.
  16. **
  17. **  4. Like many mixed-model functions, this may generate lots of warnings
  18. **     with many compilers. Despite this, it really does generate correct
  19. **     code for all major PC compilers.
  20. **
  21. **  Original Copyright 1992 by Bob Stout as part of
  22. **  the MicroFirm Function Library (MFL)
  23. **
  24. **  This subset version is hereby donated to the public domain.
  25. */
  26.  
  27. #include <dos.h>
  28. #include <io.h>
  29. #include <stdlib.h>
  30. #include <stddef.h>
  31. #include <stdio.h>
  32.  
  33. #ifdef __TURBOC__
  34.  #define FAR far
  35. #else
  36.  #define FAR _far
  37. #endif
  38.  
  39. #ifndef min
  40.  #define min(x,y) (((x) <= (y)) ? (x) : (y))
  41. #endif
  42.  
  43. #ifndef MK_FP
  44.  #define MK_FP(seg,offset) \
  45.         ((void FAR *)(((unsigned long)(seg)<<16) | (unsigned)(offset)))
  46. #endif
  47.  
  48. /*
  49. **  Get the largest buffer possible.
  50. */
  51.  
  52. static size_t gettmp(char **buf)
  53. {
  54.       size_t bufsiz;
  55.  
  56.       for (bufsiz = 0x4000; bufsiz >= 128; bufsiz >>= 1)
  57.       {
  58.             if (NULL != (*buf = (char *) malloc(bufsiz)))
  59.                   return bufsiz;
  60.       }
  61.       return 0;
  62. }
  63.  
  64. /*
  65. **  Normalize a far pointer
  66. */
  67.  
  68. void FAR *farnormal(void FAR *ptr)
  69. {
  70.       unsigned long base, para;
  71.  
  72.       base = (unsigned long)(ptr & 0xffff000fL);
  73.       para = (unsigned long)(ptr & 0x0000fff0L);
  74.       para <<= 12;
  75.       return (void FAR *)(base + para);
  76. }
  77.  
  78. /*
  79. **  Read any size block to anywhere in memory
  80. */
  81.  
  82. long hugeread(int fh, char FAR *buf, long size)
  83. {
  84.       long count;
  85.       size_t bufsiz;
  86.       char *tmp;
  87.       long ercode = size;
  88.  
  89.       if (4 > sizeof(void *))
  90.       {
  91.             if (0 == (bufsiz = gettmp(&tmp)))
  92.                   return -1L;
  93.       }
  94.       else
  95.       {
  96.             tmp = (char *)buf;
  97.             bufsiz = 0x4000;
  98.       }
  99.  
  100.       while (0 < (count = min(size, (long)bufsiz)))
  101.       {
  102.             int i, numread = read(fh, tmp, (size_t)count);
  103.  
  104.             if (1 > numread || numread != (int)count)
  105.                   return -1L;
  106.             if (4 > sizeof(void *))
  107.             {
  108.                   for (i = 0; i < count; ++i)
  109.                         buf[i] = tmp[i];
  110.             }
  111.             buf = farnormal(buf + count);
  112.             size -= count;
  113.             if (2 < sizeof(void *))
  114.                   tmp = (char *)buf;
  115.       }
  116.       return ercode;
  117. }
  118.  
  119. /*
  120. **  Write any size block from anywhere in memory
  121. */
  122.  
  123. long hugewrite(int fh, char FAR *buf, long size)
  124. {
  125.       long count;
  126.       size_t bufsiz;
  127.       char *tmp;
  128.       long ercode = size;
  129.  
  130.       if (4 > sizeof(void *))
  131.       {
  132.             if (0 == (bufsiz = gettmp(&tmp)))
  133.                   return -1L;
  134.       }
  135.       else
  136.       {
  137.             tmp = (char *)buf;
  138.             bufsiz = 0x4000;
  139.       }
  140.  
  141.       while (0 < (count = min(size, (long)bufsiz)))
  142.       {
  143.             int i, numwrite;
  144.  
  145.             if (4 > sizeof(void *))
  146.             {
  147.                   for (i = 0; i < count; ++i)
  148.                         tmp[i] = buf[i];
  149.             }
  150.             numwrite = write(fh, tmp, (size_t)count);
  151.             if (1 > numwrite || numwrite != (int)count)
  152.                   return -1L;
  153.             buf = farnormal(buf + count);
  154.             size -= count;
  155.             if (2 < sizeof(void *))
  156.                   tmp = (char *)buf;
  157.       }
  158.       return ercode;
  159. }
  160.  
  161. /*
  162. **  Read any size block to anywhere in memory
  163. */
  164.  
  165. long hugefread(FILE *fp, char FAR *buf, long size)
  166. {
  167.       long count;
  168.       size_t bufsiz;
  169.       char *tmp;
  170.       long ercode = size;
  171.  
  172.       if (4 > sizeof(void *))
  173.       {
  174.             if (0 == (bufsiz = gettmp(&tmp)))
  175.                   return -1L;
  176.       }
  177.       else
  178.       {
  179.             tmp = (char *)buf;
  180.             bufsiz = 0x4000;
  181.       }
  182.  
  183.       while (0 < (count = min(size, (long)bufsiz)))
  184.       {
  185.             int i, numread = fread(tmp, 1, (size_t)count, fp);
  186.  
  187.             if (1 > numread || numread != (int)count)
  188.                   return -1L;
  189.             if (4 > sizeof(void *))
  190.             {
  191.                   for (i = 0; i < count; ++i)
  192.                         buf[i] = tmp[i];
  193.             }
  194.             buf = farnormal(buf + count);
  195.             size -= count;
  196.             if (2 < sizeof(void *))
  197.                   tmp = (char *)buf;
  198.       }
  199.       return ercode;
  200. }
  201.  
  202. /*
  203. **  Write any size block from anywhere in memory
  204. */
  205.  
  206. long hugefwrite(FILE *fp, char FAR *buf, long size)
  207. {
  208.       long count;
  209.       size_t bufsiz;
  210.       char *tmp;
  211.       long ercode = size;
  212.  
  213.       if (4 > sizeof(void *))
  214.       {
  215.             if (0 == (bufsiz = gettmp(&tmp)))
  216.                   return -1L;
  217.       }
  218.       else
  219.       {
  220.             tmp = (char *)buf;
  221.             bufsiz = 0x4000;
  222.       }
  223.  
  224.       while (0 < (count = min(size, (long)bufsiz)))
  225.       {
  226.             int i, numwrite;
  227.  
  228.             if (4 > sizeof(void *))
  229.             {
  230.                   for (i = 0; i < count; ++i)
  231.                         tmp[i] = buf[i];
  232.             }
  233.             numwrite = fwrite(tmp, 1, (size_t)count, fp);
  234.             if (1 > numwrite || numwrite != (int)count)
  235.                   return -1L;
  236.             buf = farnormal(buf + count);
  237.             size -= count;
  238.             if (2 < sizeof(void *))
  239.                   tmp = (char *)buf;
  240.       }
  241.       return ercode;
  242. }
  243.