diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/crt32/iostream/strstrea.cxx | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/crt32/iostream/strstrea.cxx')
-rw-r--r-- | private/crt32/iostream/strstrea.cxx | 440 |
1 files changed, 440 insertions, 0 deletions
diff --git a/private/crt32/iostream/strstrea.cxx b/private/crt32/iostream/strstrea.cxx new file mode 100644 index 000000000..fba8e0126 --- /dev/null +++ b/private/crt32/iostream/strstrea.cxx @@ -0,0 +1,440 @@ + +/*** +*strstream.cxx - definitions for strstreambuf, strstream +* +* Copyright (c) 1991-1992, Microsoft Corporation. All rights reserved. +* +*Purpose: +* This file defines the functions used by strstream and strstrembuf +* classes. +* +*Revision History: +* 08-14-91 KRS Initial version. +* 08-23-91 KRS Initial version completed. +* 09-03-91 KRS Fix typo in strstreambuf::seekoff(,ios::in,) +* 09-04-91 KRS Added virtual sync() to fix flush(). Fix underflow(). +* 09-05-91 KRS Change str() and freeze() to match spec. +* 09-19-91 KRS Add calls to delbuf(1) in constructors. +* 10-24-91 KRS Avoid virtual calls from virtual functions. +* +*******************************************************************************/ + +#include <cruntime.h> +#include <internal.h> +#include <stdlib.h> +#include <string.h> +#include <strstrea.h> +#pragma hdrstop + +/*** +*strstreambuf::strstreambuf() - default constructor for strstreambuf +* +*Purpose: +* Default constructor for class strstreambuf. +* +*Entry: +* +*Exit: +* +*Exceptions: +* +*******************************************************************************/ + strstreambuf::strstreambuf() +: streambuf() +{ +x_bufmin = x_dynamic = 1; +x_static = 0; +x_alloc = (0); +x_free = (0); +// CONSIDER: do anything else?? +} + +/*** +*strstreambuf::strstreambuf(int n) - constructor for strstreambuf +* +*Purpose: +* Constructor for class strstreambuf. Created in dynamic mode. +* +*Entry: +* n = minimum size for initial allocation. +* +*Exit: +* +*Exceptions: +* +*******************************************************************************/ +strstreambuf::strstreambuf(int n) +: streambuf() +{ +x_dynamic = 1; +x_static = 0; +x_alloc = (0); +x_free = (0); +setbuf(0,n); +// CONSIDER: do anything else?? +} + +/*** +*strstreambuf::strstreambuf(void* (*_a)(long), void (*_f)(void*)) - constructor for strstreambuf +* +*Purpose: +* Construct a strstreambuf in dynamic mode. Use specified allocator +* and deallocator instead of new and delete. +* +*Entry: +* *_a = allocator: void * (*_a)(long) +* *_f = deallocator: void (*_f)(void *) +* +*Exit: +* +*Exceptions: +* +*******************************************************************************/ +strstreambuf::strstreambuf(void* (*_a)(long), void (*_f)(void*)) +: streambuf() +{ +// CONSIDER: do anything else?? +x_dynamic = x_bufmin = 1; +x_static = 0; +x_alloc = _a; +x_free = _f; +} + +/*** +*strstreambuf::strstreambuf(char * ptr, int size, char * pstart = 0) - +* +*Purpose: +* Construct a strstreambuf in static mode. Buffer used is of 'size' +* bytes. If 'size' is 0, uses a null-terminated string as buffer. +* If negative, size is considered infinite. Get starts at ptr. +* If pstart!=0, put buffer starts at pstart. Otherwise, no output. +* +*Entry: +* char * ptr; pointer to buffer base() +* int size; size of buffer, or 0= use strlen to calculate size +* or if negative size is 'infinite'. +* char * pstart; pointer to put buffer of NULL if none. +* +*Exit: +* +*Exceptions: +* +*******************************************************************************/ +strstreambuf::strstreambuf( char * ptr, int size, char * pstart) +: streambuf() +{ + x_static = 1; + x_dynamic = 0; + char * pend; + + if (!size) + pend = ptr + strlen(ptr); + else if (size < 0) + { + // size = 32767 - (unsigned short)ptr; // UNDONE: fix for 32-bit + // UNDONE: bogus segment math + pend = (char*)-1L; + } + else + pend = ptr + size; + + setb(ptr, pend,0); +// CONSIDER: is this right? Not quite what spec. says... + if (pstart) + { + setg(ptr,ptr,pstart); + setp(pstart, pend); + } + else + { + setg(ptr,ptr,pend); + setp(0, 0); + } +} + +strstreambuf::~strstreambuf() +{ + if ((x_dynamic) && (base())) + { + if (x_free) + { + (*x_free)(base()); + } + else + { + delete base(); + } + } +// x_dynamic = 0; +// x_static = 1; +} + +void strstreambuf::freeze(int n) +{ + if (!x_static) + x_dynamic = (!n); +} + +char * strstreambuf::str() +{ +// x_static = 1; // CONSIDER: disallow further dynamic changes? + + x_dynamic = 0; // freeze(); + + return base(); +} + +int strstreambuf::doallocate() +{ + char * bptr; + int size; + size = __max(x_bufmin,blen()+1); + long offset = 0; + + if (x_alloc) + { + bptr = (char*)(*x_alloc)(size); + } + else + { + bptr = new char[size]; + } + if (!bptr) + return EOF; + + if (blen()) + { + memcpy(bptr, base(), blen()); + offset = bptr - base(); // amount to adjust pointers by + } + if (x_free) + { + (*x_free)(base()); + } + else + { + delete base(); + } + setb(bptr,bptr+size,0); // we handle deallocation + + // adjust get/put pointers too, if necessary + if (offset) + if (egptr()) + { + setg(eback()+offset,gptr()+offset,egptr()+offset); + } + if (epptr()) + { + size = pptr() - pbase(); + setp(pbase()+offset,epptr()+offset); + pbump(size); + } + return(1); +} + +streambuf * strstreambuf::setbuf( char *, int l) +{ + if (l) + x_bufmin = l; + return this; +} + +int strstreambuf::overflow(int c) +{ +/* +- if no room and not dynamic, give error +- if no room and dynamic, allocate (1 more or min) and store +- if and when the buffer has room, store c if not EOF +*/ + int temp; + if (pptr() >= epptr()) + { + if (!x_dynamic) + return EOF; + + if (strstreambuf::doallocate()==EOF) + return EOF; + + if (!epptr()) // init if first time through + { + setp(base() + (egptr() - eback()),ebuf()); + } + else + { + temp = pptr()-pbase(); + setp(pbase(),ebuf()); + pbump(temp); + } + } + + if (c!=EOF) + { + *pptr() = (char)c; + pbump(1); // UNDONE: + } + return(1); +} + +int strstreambuf::underflow() +{ + char * tptr; + if (gptr() >= egptr()) + { + // try to grow get area if we can... + if (egptr()<pptr()) + { + tptr = base() + (gptr()-eback()); + setg(base(),tptr,pptr()); + } + if (gptr() >= egptr()) + return EOF; + } + + return *gptr(); +} + +int strstreambuf::sync() +{ +// a strstreambuf is always in sync, by definition! +return 0; +} + +streampos strstreambuf::seekoff(streamoff off, ios::seek_dir dir, int mode) +{ +char * tptr; +long offset = EOF; // default return value + if (mode & ios::in) + { + strstreambuf::underflow(); // makes sure entire buffer available + switch (dir) { + case ios::beg : + tptr = eback(); + break; + case ios::cur : + tptr = gptr(); + break; + case ios::end : + tptr = egptr(); + break; + default: + return EOF; + } + tptr += off; + offset = tptr - eback(); + if ((tptr < eback()) || (tptr > egptr())) + { + return EOF; + } + gbump(tptr-gptr()); + } + if (mode & ios::out) + { + if (!epptr()) + { + if (strstreambuf::overflow(EOF)==EOF) // make sure there's a put buffer + return EOF; + } + switch (dir) { + case ios::beg : + tptr = pbase(); + break; + case ios::cur : + tptr = pptr(); + break; + case ios::end : + tptr = epptr(); + break; + default: + return EOF; + } + tptr += off; + offset = tptr - pbase(); + if (tptr < pbase()) + return EOF; + if (tptr > epptr()) + { + if (x_dynamic) + { + x_bufmin = __max(x_bufmin, (tptr-pbase())); + if (strstreambuf::doallocate()==EOF) + return EOF; + // _epptr = ebuf(); + } + else + return EOF; + } + pbump(tptr-pptr()); + } + return offset; // note: if both in and out set, returns out offset +} + + + istrstream::istrstream(char * pszStr) +: istream(new strstreambuf(pszStr,0)) +{ + delbuf(1); + // CONSIDER: do anything else? +} + + istrstream::istrstream(char * pStr, int len) +: istream(new strstreambuf(pStr,len)) +{ + delbuf(1); + // CONSIDER: do anything else? +// CONSIDER: do anything else? +} + + istrstream::~istrstream() +{ +// CONSIDER: do anything else? +} + + ostrstream::ostrstream() +: ostream(new strstreambuf) +{ + delbuf(1); + // CONSIDER: do anything else? +// CONSIDER: do anything else? +} + + ostrstream::ostrstream(char * str, int size, int mode) +: ostream(new strstreambuf(str,size,str)) +{ + delbuf(1); + if (mode & (ios::app|ios::ate)) + seekp(strlen(str),ios::beg); +// CONSIDER: needed? +// rdbuf()->setg(0,0,0); // no input allowed +// CONSIDER: do anything else? +} + + ostrstream::~ostrstream() +{ +// CONSIDER: do anything else? +} + + strstream::strstream() +: iostream(new strstreambuf) +{ + istream::delbuf(1); + ostream::delbuf(1); + // CONSIDER: do anything else? +} + + strstream::strstream(char * str, int size, int mode) +: iostream(new strstreambuf(str,size,str)) +{ +// UNDONE: not quite correct! + + istream::delbuf(1); + ostream::delbuf(1); + if ((mode & ostream::out) && (mode & (ostream::app|ostream::ate))) + seekp(strlen(str),ostream::beg); +// rdbuf()->setg(rdbuf()->base(),rdbuf()->base(),rdbuf()->ebuf()); // UNDONE: how is input handled??? +// CONSIDER: do anything else? +} + + strstream::~strstream() +{ +// CONSIDER: do anything else? +} |