void NXCloseMemory(register NXStream *s, int option) { int userBuf; int isCheapStream; _NXVerifyStream(s); verify_memory_stream(s); isCheapStream = (s->functions == &cheap_functions) ? 1:0; userBuf = (s->flags & NX_USER_OWNS_BUF) != 0; if (!userBuf) { switch (option) { case NX_FREEBUFFER: if (isCheapStream && s->buf_size < MAX_MALLOC) free(s->buf_base); else { kern_return_t ret = vm_deallocate(mach_task_self(), (vm_offset_t)s->buf_base, (vm_size_t)s->buf_size); if (ret != KERN_SUCCESS) NX_RAISE(NX_streamVMError, s, (void *)ret); } break; case NX_TRUNCATEBUFFER: if (!isCheapStream || s->buf_size >= MAX_MALLOC) memory_close(s); break; case NX_SAVEBUFFER: break; } } NXStreamDestroy(s); }
void NXSeek(register NXStream *s, long offset, int ptrname) { long curPos; _NXVerifyStream(s); curPos = NXTell(s); if (curPos > s->eof) s->eof = curPos; switch (ptrname) { case NX_FROMSTART: break; case NX_FROMCURRENT: offset += NXTell(s); break; case NX_FROMEND: offset += s->eof; break; default: NX_RAISE( NX_illegalSeek, s, 0 ); } if ( offset < 0 // || !(s->flags&NX_CANSEEK) *** This breaks too much code *** || ( (s->flags & NX_READFLAG) && !(s->flags & NX_CANWRITE) && (offset > s->eof)) ) NX_RAISE( NX_illegalSeek, s, 0 ); if (s->flags & NX_EOS && offset < s->eof) s->flags &= ~NX_EOS; else if (offset >= s->eof) s->flags |= NX_EOS; s->functions->seek(s, offset); }
int NXSaveToFile(register NXStream *s, const char *name ) { int fd; char *buf; int len, max, retval; _NXVerifyStream(s); verify_memory_stream(s); fd = open(name, O_WRONLY | O_CREAT, 0666); if (fd >= 0) { NXGetMemoryBuffer(s, &buf, &len, &max); retval = write(fd, buf, len); if (retval < 0) return retval; retval = ftruncate(fd, len); if (retval < 0) return retval; retval = fsync(fd); if (retval < 0) return retval; retval = close(fd); if (retval < 0) return retval; } else return -1; return 0; }
void NXClose(register NXStream *s) { _NXVerifyStream(s); if (s->flags & NX_WRITEFLAG) (void)NXFlush(s); s->functions->destroy(s); NXStreamDestroy(s); }
extern int _NXStreamFlushBuffer(NXStream *s, unsigned char c) { _NXVerifyStream(s); s->buf_left++; /* compensate for NXPutc */ (void)NXFlush(s); *s->buf_ptr++ = c; s->buf_left--; return (int)c; }
void NXPrintf(NXStream *stream, const char *format, ...) { va_list ap; _NXVerifyStream(stream); va_start(ap, format); NXVPrintf(stream, format, ap); va_end(ap); }
void NXGetMemoryBuffer(NXStream *s, char **addr, int *len, int *maxlen) { int bufSize = s->buf_size - s->buf_left; _NXVerifyStream(s); verify_memory_stream(s); *addr = (char *)s->buf_base; *len = ((s->flags&NX_READFLAG) || (bufSize <= s->eof)) ? s->eof : bufSize; *maxlen = s->buf_size; }
int NXScanf(NXStream *stream, const char *format, ...) { va_list ap; int ret; _NXVerifyStream(stream); va_start(ap, format); ret = NXVScanf(stream, format, ap); va_end(ap); return ret; }
long NXTell(register NXStream *s) { _NXVerifyStream(s); if (s->flags & NX_READFLAG) { return s->offset + (s->buf_ptr - s->buf_base); } else if (s->flags & NX_WRITEFLAG) { return s->offset + s->buf_size - s->buf_left; } else { fprintf(stderr, "Stream is neither readable nor writable in NXTell\n"); return -1; } }
void NXUngetc(register NXStream *s) { _NXVerifyStream(s); if (NXTell(s) > 0) { if (s->buf_ptr == s->buf_base) fprintf(stderr, "Assertion failed: NXUngetc: last character read unknown\n"); else if (!(s->flags & NX_EOS)) { s->buf_left++; s->buf_ptr--; } } }
extern int _NXStreamChangeBuffer(NXStream *s, unsigned char ch) { int wasReading; _NXVerifyStream(s); wasReading = (s->flags & NX_READFLAG); NXChangeBuffer(s); if (wasReading) NXPutc(s, ch); else ch = NXGetc(s); return ((int)(ch)); }
extern int _NXStreamFillBuffer(NXStream *s) { int n; _NXVerifyStream(s); if (s->flags & NX_EOS) return -1; if (s->buf_left < 0) s->buf_left = 0; n = NXFill(s); if (n <= 0) { s->flags |= NX_EOS; return -1; } s->buf_left--; return ((int)((*(s->buf_ptr++)) & 0xff)); }
__private_extern__ int NXDefaultWrite(NXStream *s, const void *buf, int count) { register int n; int total = count; int curPos; const char * volatile bufPtr = buf; NXHandler exception; _NXVerifyStream(s); /* * Loop until copying complete. */ exception.code = 0; if (s->flags & NX_READFLAG) NXChangeBuffer(s); while (count > 0) { /* * Flush buffer if necessary. */ if (s->buf_left == 0) { NX_DURING { (void)NXFlush(s); } NX_HANDLER { exception = NXLocalHandler; break; } NX_ENDHANDLER } /* * Figure out how much to copy this time. */ n = count; if (n > s->buf_left) n = s->buf_left; bcopy((const char *)bufPtr, s->buf_ptr, n); /* * Update all pointers. */ s->buf_ptr += n; s->buf_left -= n; bufPtr += n; count -= n; }
int NXVScanf(NXStream *stream, register const char *fmt, va_list arg) { register int ch; int nmatch, len, ch1; void *ptr; int fileended, size; char _sctab[SCTAB_SIZE]; _NXVerifyStream(stream); bzero( _sctab, SCTAB_SIZE ); _sctab[9] = _sctab[10] = _sctab[32] = SPC; nmatch = 0; fileended = 0; for (;;) switch (ch = *fmt++) { case '\0': return (nmatch); case '%': if ((ch = *fmt++) == '%') goto def; ptr = 0; if (ch != '*') ptr = va_arg(arg, void *); else ch = *fmt++; len = 0; size = REGULAR; while (isdigit(ch)) { len = len*10 + ch - '0'; ch = *fmt++; } if (len == 0) len = 30000; if (ch=='l') { size = LONG; ch = *fmt++; } else if (ch=='h') { size = SHORT; ch = *fmt++; } else if (ch=='[') fmt = _getccl(fmt, _sctab); if (isupper(ch)) { ch = tolower(ch); size = LONG; } if (ch == '\0') return(-1); if (_innum(ptr, ch, len, size, stream, &fileended, _sctab) && ptr) nmatch++; if (fileended) return(nmatch? nmatch: -1); break; case ' ': case '\n': case '\t': while ((ch1 = NXGetc(stream))==' ' || ch1=='\t' || ch1=='\n') ; if (ch1 != EOF) NXUngetc(stream); break; default: def: ch1 = NXGetc(stream); if (ch1 != ch) { if (ch1==EOF) return(-1); NXUngetc(stream); return(nmatch); } }