From 7e0f021a9aec35fd8e6725e87e3313b101d26f5e Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 27 Jan 2008 11:37:44 +0100 Subject: Initial import (2.0.2-6) --- reference/C/CONTRIB/SNIP/hugeread.c | 242 ++++++++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100755 reference/C/CONTRIB/SNIP/hugeread.c (limited to 'reference/C/CONTRIB/SNIP/hugeread.c') diff --git a/reference/C/CONTRIB/SNIP/hugeread.c b/reference/C/CONTRIB/SNIP/hugeread.c new file mode 100755 index 0000000..fa981c6 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/hugeread.c @@ -0,0 +1,242 @@ +/* +** HUGEREAD.C - "Universal" PC read and write functions using huge data +** and far pointers. +** +** NOTES: +** +** 1. If these functions are called with a prototype in scope, passed +** parameters will be coerced to the proper data types. +** +** 2. Since these call read() and write(), all normal mode flags which +** are supported by individual compilers will be honored. +** +** 3. In small data memory models (S, T, and M), an intermediate buffer +** is allocated and used. In large data models (L and C), the data +** are read/written directly from/to target memory. +** +** 4. Like many mixed-model functions, this may generate lots of warnings +** with many compilers. Despite this, it really does generate correct +** code for all major PC compilers. +** +** Original Copyright 1992 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is hereby donated to the public domain. +*/ + +#include +#include +#include +#include +#include + +#ifdef __TURBOC__ + #define FAR far +#else + #define FAR _far +#endif + +#ifndef min + #define min(x,y) (((x) <= (y)) ? (x) : (y)) +#endif + +#ifndef MK_FP + #define MK_FP(seg,offset) \ + ((void FAR *)(((unsigned long)(seg)<<16) | (unsigned)(offset))) +#endif + +/* +** Get the largest buffer possible. +*/ + +static size_t gettmp(char **buf) +{ + size_t bufsiz; + + for (bufsiz = 0x4000; bufsiz >= 128; bufsiz >>= 1) + { + if (NULL != (*buf = (char *) malloc(bufsiz))) + return bufsiz; + } + return 0; +} + +/* +** Normalize a far pointer +*/ + +void FAR *farnormal(void FAR *ptr) +{ + unsigned long base, para; + + base = (unsigned long)(ptr & 0xffff000fL); + para = (unsigned long)(ptr & 0x0000fff0L); + para <<= 12; + return (void FAR *)(base + para); +} + +/* +** Read any size block to anywhere in memory +*/ + +long hugeread(int fh, char FAR *buf, long size) +{ + long count; + size_t bufsiz; + char *tmp; + long ercode = size; + + if (4 > sizeof(void *)) + { + if (0 == (bufsiz = gettmp(&tmp))) + return -1L; + } + else + { + tmp = (char *)buf; + bufsiz = 0x4000; + } + + while (0 < (count = min(size, (long)bufsiz))) + { + int i, numread = read(fh, tmp, (size_t)count); + + if (1 > numread || numread != (int)count) + return -1L; + if (4 > sizeof(void *)) + { + for (i = 0; i < count; ++i) + buf[i] = tmp[i]; + } + buf = farnormal(buf + count); + size -= count; + if (2 < sizeof(void *)) + tmp = (char *)buf; + } + return ercode; +} + +/* +** Write any size block from anywhere in memory +*/ + +long hugewrite(int fh, char FAR *buf, long size) +{ + long count; + size_t bufsiz; + char *tmp; + long ercode = size; + + if (4 > sizeof(void *)) + { + if (0 == (bufsiz = gettmp(&tmp))) + return -1L; + } + else + { + tmp = (char *)buf; + bufsiz = 0x4000; + } + + while (0 < (count = min(size, (long)bufsiz))) + { + int i, numwrite; + + if (4 > sizeof(void *)) + { + for (i = 0; i < count; ++i) + tmp[i] = buf[i]; + } + numwrite = write(fh, tmp, (size_t)count); + if (1 > numwrite || numwrite != (int)count) + return -1L; + buf = farnormal(buf + count); + size -= count; + if (2 < sizeof(void *)) + tmp = (char *)buf; + } + return ercode; +} + +/* +** Read any size block to anywhere in memory +*/ + +long hugefread(FILE *fp, char FAR *buf, long size) +{ + long count; + size_t bufsiz; + char *tmp; + long ercode = size; + + if (4 > sizeof(void *)) + { + if (0 == (bufsiz = gettmp(&tmp))) + return -1L; + } + else + { + tmp = (char *)buf; + bufsiz = 0x4000; + } + + while (0 < (count = min(size, (long)bufsiz))) + { + int i, numread = fread(tmp, 1, (size_t)count, fp); + + if (1 > numread || numread != (int)count) + return -1L; + if (4 > sizeof(void *)) + { + for (i = 0; i < count; ++i) + buf[i] = tmp[i]; + } + buf = farnormal(buf + count); + size -= count; + if (2 < sizeof(void *)) + tmp = (char *)buf; + } + return ercode; +} + +/* +** Write any size block from anywhere in memory +*/ + +long hugefwrite(FILE *fp, char FAR *buf, long size) +{ + long count; + size_t bufsiz; + char *tmp; + long ercode = size; + + if (4 > sizeof(void *)) + { + if (0 == (bufsiz = gettmp(&tmp))) + return -1L; + } + else + { + tmp = (char *)buf; + bufsiz = 0x4000; + } + + while (0 < (count = min(size, (long)bufsiz))) + { + int i, numwrite; + + if (4 > sizeof(void *)) + { + for (i = 0; i < count; ++i) + tmp[i] = buf[i]; + } + numwrite = fwrite(tmp, 1, (size_t)count, fp); + if (1 > numwrite || numwrite != (int)count) + return -1L; + buf = farnormal(buf + count); + size -= count; + if (2 < sizeof(void *)) + tmp = (char *)buf; + } + return ercode; +} -- cgit v1.2.3-54-g00ecf