int filebuf::overflow(int c) { if (xflags() & _S_NO_WRITES) // SET ERROR return EOF; // Allocate a buffer if needed. if (base() == NULL) { doallocbuf(); if (xflags() & _S_LINE_BUF+_S_UNBUFFERED) setp(_base, _base); else setp(_base, _ebuf); setg(_base, _base, _base); _flags |= _S_CURRENTLY_PUTTING; } // If currently reading, switch to writing. else if ((_flags & _S_CURRENTLY_PUTTING) == 0) { if (xflags() & _S_LINE_BUF+_S_UNBUFFERED) setp(gptr(), gptr()); else setp(gptr(), ebuf()); setg(egptr(), egptr(), egptr()); _flags |= _S_CURRENTLY_PUTTING; } if (c == EOF) return do_flush(); if (pptr() == ebuf() ) // Buffer is really full if (do_flush() == EOF) return EOF; xput_char(c); if (unbuffered() || (linebuffered() && c == '\n')) if (do_flush() == EOF) return EOF; return (unsigned char)c; }
int general_parsebuf::underflow() { register char *ptr = base(); int has_newline = eback() < gptr() && gptr()[-1] == '\n'; if (has_newline) *ptr++ = '\n'; register streambuf *sb = sbuf; register int ch; for (;;) { ch = sb->sbumpc(); if (ch == EOF) break; if (ptr == ebuf()) { int old_size = ebuf() - base(); char *new_buffer = new char[old_size * 2]; memcpy(new_buffer, base(), old_size); setb(new_buffer, new_buffer + 2 * old_size, 1); ptr = new_buffer + old_size; } *ptr++ = ch; if (ch == '\n') break; } char *cur_pos = base() + has_newline; pos_at_line_start += _line_length + 1; _line_length = ptr - cur_pos; if (ch != EOF || _line_length > 0) __line_number++; setg(base(), cur_pos, ptr); return ptr == cur_pos ? EOF : cur_pos[0]; }
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); } return(1); }
int filebuf::do_write(const char *data, int to_do) { if (to_do == 0) return 0; if (xflags() & _S_IS_APPENDING) { // On a system without a proper O_APPEND implementation, // you would need to sys_seek(0, ios::end) here, but is // is not needed nor desirable for Unix- or Posix-like systems. // Instead, just indicate that offset (before and after) is // unpredictable. _fb._offset = -1; } else if (egptr() != pbase()) { long new_pos = sys_seek(pbase()-egptr(), ios::cur); if (new_pos == -1) return EOF; _fb._offset = new_pos; } _G_ssize_t count = sys_write(data, to_do); if (_cur_column) _cur_column = __adjust_column(_cur_column - 1, data, to_do) + 1; setg(base(), base(), base()); if (xflags() & _S_LINE_BUF+_S_UNBUFFERED) setp(base(), base()); else setp(base(), ebuf()); return count != to_do ? EOF : 0; }
ostream & SMKStrStreambuf::dumpInfo( ostream & dest, const char * prefix, bool showVer ) { if( showVer ) dest << SMKStrStreambuf::getClassName() << ":\n" << SMKStrStreambuf::getVersion() << '\n'; dest << prefix << "length: " << plen() << '\n' #if defined( SMK_HAVE_STRBUF_BASE ) << prefix << "base(): " << (void *) base() << '\n' #endif #if defined( SMK_HAVE_STRBUF_EBUF ) << prefix << "ebuf(): " << (void *) ebuf() << '\n' #endif << prefix << "pbase(): " << (void *) pbase() << '\n' << prefix << "pptr(): " << (void *) pptr() << '\n' << prefix << "epptr(): " << (void *) epptr() << '\n' << prefix << "eback(): " << (void *) eback() << '\n' << prefix << "gptr(): " << (void *) gptr() << '\n' << prefix << "egptr(): " << (void *) egptr() << '\n' << prefix << "n - b: " << pptr() - pbase() << '\n' << prefix << "string: '" << (void *)cstr() << "'\n" << prefix << "pbase(): " << (void *) pbase() << '\n' << prefix << "pptr(): " << (void *) pptr() << '\n' << prefix << "length: " << plen() << '\n' << prefix << "size: " << psize() << '\n' ; return( dest ); }
int rpcbuf::underflow() { if (!_opened || allocate() == EOF) { return EOF; } if (overflow() == EOF) { return EOF; } int nunread = in_avail(); if (nunread) { Memory::copy(gptr(), eback(), nunread); } setg(eback(), eback(), eback() + nunread); int nread = read(_fd, egptr(), ebuf() - egptr()); if (nread < 0) { sys_error("rpcbuf::underflow: read"); return EOF; } if (nread == 0) { return EOF; } setg(eback(), gptr(), egptr() + nread); return zapeof(*gptr()); }
string_parsebuf::string_parsebuf(char *buf, int len, int delete_at_close /* = 0*/) : parsebuf() { setb(buf, buf+len, delete_at_close); register char *ptr = buf; while (ptr < ebuf() && *ptr != '\n') ptr++; _line_length = ptr - buf; setg(buf, buf, ptr); }
streambuf* PRfilebuf::setbuf(char *buffptr, int bufflen) { if (is_open() && (ebuf())) return 0; if ((!buffptr) || (bufflen <= 0)) unbuffered(1); else setb(buffptr, buffptr+bufflen, 0); return this; }
/*** *virtual streambuf* filebuf::setbuf(char* ptr, int len) - set reserve area. * *Purpose: * Synchronizes buffer with external file, by flushing any output and/or * discarding any unread input data. Discards any get or put area(s). * *Entry: * ptr = requested reserve area. If NULL, request is for unbuffered. * len = size of reserve area. If <= 0, request is for unbuffered. * *Exit: * Returns this pointer if request is honored, else NULL. * *Exceptions: * Returns NULL if request is not honored. * *******************************************************************************/ streambuf * filebuf::setbuf(char * ptr, int len) { if (is_open() && (ebuf())) return NULL; if ((!ptr) || (len <= 0)) unbuffered(1); else { lock(); setb(ptr, ptr+len, 0); unlock(); } return this; }
void strstreambuf::init( signed char* ptr, int n, signed char* pstart ) { ssbflags = 0; if( n == 0 ) n = strlen((char*)ptr); else if( n < 0 ) { n = INT_MAX; ssbflags |= unlimited; // distinguish it from merely large } setb((char*)ptr, (char*)ptr+n, 0); if( pstart ) { setp((char*)pstart, ebuf()); setg((char*)ptr, (char*)ptr, (pstart > ptr+n) ? (char *)ptr+n: (char*)pstart); } else setg((char*)ptr, (char*)ptr, (char*)ebuf()); allocf = 0; freef = 0; }
/*** *filebuf* filebuf::attach(filedesc fd) - filebuf attach function * *Purpose: * filebuf attach() member function. Attach filebuf object to the * given file descriptor previously obtained from _open() or _sopen(). * *Entry: * fd = file descriptor. * *Exit: * Returns this pointer or NULL if error. * *Exceptions: * Returns NULL if fd = -1. * *******************************************************************************/ filebuf* filebuf::attach(filedesc fd) { if (x_fd!=-1) return NULL; // error if already attached lock(); x_fd = fd; if ((fd!=-1) && (!unbuffered()) && (!ebuf())) { char * sbuf = _new_crt char[BUFSIZ]; if (!sbuf) { unbuffered(1); } else { streambuf::setb(sbuf,sbuf+BUFSIZ,1); } }
int PRfilebuf::overflow(int c) { if (allocate()==EOF) // make sure there is a reserve area return EOF; if (PRfilebuf::sync()==EOF) // sync before new buffer created below return EOF; if (!unbuffered()) setp(base(),ebuf()); if (c!=EOF){ if ((!unbuffered()) && (pptr() < epptr())) // guard against recursion sputc(c); else{ if (PR_Write(_fd, &c, 1)!=1) return(EOF); } } return(1); // return something other than EOF if successful }
int rpcbuf::read_request() { if (!_mystream) { return EOF; } if (!_actualWidth) { char* orig = pptr(); const int length = 0; mystream().width(FIELDWIDTH); mystream() << length; _actualWidth = pptr() - orig; pbump(orig - pptr()); } int navail = in_avail(); if (navail < _actualWidth) { return EOF; } char* orig = gptr(); int length = 0; mystream() >> length; gbump(orig - gptr()); if (length <= 0) { error("rpcbuf::read_request: zero or negative length"); return EOF; } if (length > ebuf() - eback() && !expand_g(length * 2)) { error("rpcbuf::read_request: out of memory"); return EOF; } if (navail < length) { return EOF; } else { return 0; } }
int filebuf::underflow() { #if 0 /* SysV does not make this test; take it out for compatibility */ if (fp->_flags & __SEOF) return (EOF); #endif if (xflags() & _S_NO_READS) return EOF; if (gptr() < egptr()) return *(unsigned char*)gptr(); allocbuf(); // FIXME This can/should be moved to __streambuf ?? if ((xflags() & _S_LINE_BUF) || unbuffered()) { // Flush all line buffered files before reading. streambuf::flush_all_linebuffered(); } #if 1 if (pptr() > pbase()) if (do_flush()) return EOF; #endif _G_ssize_t count = sys_read(base(), ebuf() - base()); if (count <= 0) { if (count == 0) xsetflags(_S_EOF_SEEN); else xsetflags(_S_ERR_SEEN), count = 0; } setg(base(), base(), base() + count); setp(base(), base()); if (count == 0) return EOF; if (_fb._offset >= 0) _fb._offset += count; return *(unsigned char*)gptr(); }
/*** *olebuf* olebuf::attach(filedesc fd) - olebuf attach function * *Purpose: * olebuf attach() member function. Attach olebuf object to the * given file descriptor previously obtained from _open() or _sopen(). * *Entry: * fd = file descriptor. * *Exit: * Returns this pointer or NULL if error. * *Exceptions: * Returns NULL if fd = -1. * *******************************************************************************/ olebuf* olebuf::attach(IStream *pIStrm) { if (x_pIStrm!=NULL) return NULL; // error if already attached lock(); x_pIStrm = pIStrm; if (x_pIStrm) x_pIStrm -> AddRef(); if ((pIStrm!=NULL) && (!unbuffered()) && (!ebuf())) { char * sbuf = new char[BUFSIZ]; if (!sbuf) { unbuffered(1); } else { streambuf::setb(sbuf,sbuf+BUFSIZ,1); } } unlock(); return this; }
int filebuf::overflow( int c ) { unsigned int waiting; int written; streamoff offset; __lock_it( __b_lock ); // Flush any input waiting in the buffer: if( in_avail() > 0 ) { // note that sync() will discard get area if( sync() == EOF ) { return( EOF ); } } else { // discard get area setg( NULL, NULL, NULL ); } // Try to allocate a buffer: if( base() == NULL ) { if( allocate() == EOF ) { return( EOF ); } if( base() == NULL ) { if( c != EOF ) { char charbuf = (char)c; written = ::write( fd(), &charbuf, sizeof( charbuf ) ); return( written == sizeof( charbuf ) ? __NOT_EOF : EOF ); } return( __NOT_EOF ); } else { setp( base(), ebuf() ); } } else if( pptr() <= pbase() ) { setp( base(), ebuf() ); } // if appending, remember current offset and seek to end if( __file_mode & ios::app ) { offset = tell( fd() ); if( offset < 0 ) { return( EOF ); } if( lseek( fd(), 0, ios::end ) < 0 ) { return( EOF ); } } // Now write the output: if( (c != EOF) && (pptr() < epptr()) ) { *(pptr()) = (char)c; pbump( 1 ); c = EOF; } waiting = (__huge_ptr_int)(pptr() - pbase()); while( waiting > 0 ) { written = ::write( fd(), pbase(), (waiting>INT_MAX?INT_MAX:waiting) ); if( written == -1 ) { return( EOF ); } else if( written == 0 ) { break; } waiting -= written; if( waiting > 0 ) { ::memmove( pbase(), pbase() + written, waiting ); setp( pbase(), epptr() ); pbump( waiting ); } else { setp( pbase(), epptr() ); } } if( c != EOF ) { if( pptr() < epptr() ) { *(pptr()) = (char)c; pbump( 1 ); } else { return( EOF ); } } // if appending, restore current offset if( __file_mode & ios::app ) { if( lseek( fd(), offset, ios::beg ) < 0 ) { return( EOF ); } } if( waiting ) { return( EOF ); } return( __NOT_EOF ); }
streampos filebuf::seekoff(streamoff offset, _seek_dir dir, int mode) { streampos result, new_offset, delta; _G_ssize_t count; if (mode == 0) // Don't move any pointers. dir = ios::cur, offset = 0; // Flush unwritten characters. // (This may do an unneeded write if we seek within the buffer. // But to be able to switch to reading, we would need to set // egptr to ptr. That can't be done in the current design, // which assumes file_ptr() is eGptr. Anyway, since we probably // end up flushing when we close(), it doesn't make much difference.) if (pptr() > pbase() || put_mode()) if (switch_to_get_mode()) return EOF; if (base() == NULL) { doallocbuf(); setp(base(), base()); setg(base(), base(), base()); } switch (dir) { case ios::cur: if (_fb._offset < 0) { _fb._offset = sys_seek(0, ios::cur); if (_fb._offset < 0) return EOF; } // Make offset absolute, assuming current pointer is file_ptr(). offset += _fb._offset; offset -= _egptr - _gptr; if (in_backup()) offset -= _other_egptr - _other_gbase; dir = ios::beg; break; case ios::beg: break; case ios::end: struct stat st; if (sys_stat(&st) == 0 && S_ISREG(st.st_mode)) { offset += st.st_size; dir = ios::beg; } else goto dumb; } // At this point, dir==ios::beg. // If destination is within current buffer, optimize: if (_fb._offset >= 0 && _eback != NULL) { // Offset relative to start of main get area. fpos_t rel_offset = offset - _fb._offset + (eGptr()-Gbase()); if (rel_offset >= 0) { if (in_backup()) switch_to_main_get_area(); if (rel_offset <= _egptr - _eback) { setg(base(), base() + rel_offset, egptr()); setp(base(), base()); return offset; } // If we have streammarkers, seek forward by reading ahead. if (have_markers()) { int to_skip = rel_offset - (_gptr - _eback); if (ignore(to_skip) != to_skip) goto dumb; return offset; } } if (rel_offset < 0 && rel_offset >= Bbase() - Bptr()) { if (!in_backup()) switch_to_backup_area(); gbump(_egptr + rel_offset - gptr()); return offset; } } unsave_markers(); // Try to seek to a block boundary, to improve kernel page management. new_offset = offset & ~(ebuf() - base() - 1); delta = offset - new_offset; if (delta > ebuf() - base()) { new_offset = offset; delta = 0; } result = sys_seek(new_offset, ios::beg); if (result < 0) return EOF; if (delta == 0) count = 0; else { count = sys_read(base(), ebuf()-base()); if (count < delta) { // We weren't allowed to read, but try to seek the remainder. offset = count == EOF ? delta : delta-count; dir = ios::cur; goto dumb; } } setg(base(), base()+delta, base()+count); setp(base(), base()); _fb._offset = result + count; xflags(xflags() & ~ _S_EOF_SEEN); return offset; dumb: unsave_markers(); result = sys_seek(offset, dir); if (result != EOF) { xflags(xflags() & ~_S_EOF_SEEN); } _fb._offset = result; setg(base(), base(), base()); setp(base(), base()); return result; }
/*** *olebuf* olebuf::open(const char* name, int mode, int share) - olebuf open * *Purpose: * olebuf open() member function. Open a file and attach to olebuf * object. * *Entry: * name = file name string. * mode = open mode: Combination of ios:: in, out, binary, nocreate, app, * ate, noreplace and trunc. See spec. for details on behavior. * share = share mode (optional). sh_compat, sh_none, sh_read, sh_write. * *Exit: * Returns this pointer or NULL if error. * *Exceptions: * Returns NULL if olebuf is already attached to an open file, or if * invalid mode options, or if call to _sopen or olebuf::seekoff() fails. * *******************************************************************************/ olebuf* olebuf::open(IStorage *pIStg, const wchar_t* name, int mode, int share) { DWORD ole_mode = 0; if (x_pIStrm!=NULL) return NULL; // error if already open // translate mode argument if (!(mode & ios::nocreate)) ole_mode |= STGM_CREATE; if (mode & ios::noreplace) ole_mode |= STGM_FAILIFTHERE; if (mode & ios::app) { mode |= ios::out; // ole_mode |= O_APPEND; } if (mode & ios::trunc) { mode |= ios::out; // IMPLIED // ole_mode |= O_TRUNC; } if (mode & ios::out) { if (mode & ios::in) { ole_mode |= STGM_READWRITE; } else { ole_mode |= STGM_WRITE; } if (!(mode & (ios::in|ios::app|ios::ate|ios::noreplace))) { mode |= ios::trunc; // IMPLIED // ole_mode |= O_TRUNC; } } else if (mode & ios::in) ole_mode |= STGM_READ; else return NULL; // error if not ios:in or ios::out share &= (sh_read|sh_write|sh_none); // ignore other bits if (share) // optimization openprot serves as default { switch (share) { /* case 03000 : Reserved for sh_compat */ // case sh_none : case 04000 : ole_mode |= STGM_SHARE_EXCLUSIVE; break; // case sh_read : case 05000 : ole_mode |= STGM_SHARE_DENY_WRITE; break; // case sh_write : case 06000 : ole_mode |= STGM_SHARE_DENY_READ; break; // case (sh_read|sh_write) : case 07000 : ole_mode |= STGM_SHARE_DENY_NONE; break; default : // unrecognized value same as default break; }; } HRESULT hr; if (ole_mode & STGM_CREATE) // create new substream hr = pIStg -> CreateStream (name, ole_mode, 0L, 0L, &x_pIStrm); else // open existing stream hr = pIStg -> OpenStream (name, NULL, ole_mode, 0L, &x_pIStrm); if (FAILED(hr)) { SetLastError (hr); return NULL; } lock(); x_fOpened = 1; if ((!unbuffered()) && (!ebuf())) { char * sbuf = new char[BUFSIZ]; if (!sbuf) { unbuffered(1); } else { streambuf::setb(sbuf,sbuf+BUFSIZ,1); } } if (mode & ios::ate) if (seekoff(0,ios::end,mode)==EOF) { close(); unlock(); return NULL; } unlock(); return this; }
PRfilebuf* PRfilebuf::open(const char *name, int mode, int flags) { if (_fd != 0) return 0; // error if already open PRIntn PRmode = 0; // translate mode argument if (!(mode & ios::nocreate)) PRmode |= PR_CREATE_FILE; //if (mode & ios::noreplace) // PRmode |= O_EXCL; if (mode & ios::app){ mode |= ios::out; PRmode |= PR_APPEND; } if (mode & ios::trunc){ mode |= ios::out; // IMPLIED PRmode |= PR_TRUNCATE; } if (mode & ios::out){ if (mode & ios::in) PRmode |= PR_RDWR; else PRmode |= PR_WRONLY; if (!(mode & (ios::in|ios::app|ios::ate|ios::noreplace))){ mode |= ios::trunc; // IMPLIED PRmode |= PR_TRUNCATE; } }else if (mode & ios::in) PRmode |= PR_RDONLY; else return 0; // error if not ios:in or ios::out // // The usual portable across unix crap... // NT gets a hokey piece of junk layer that prevents // access to the API. #ifdef WIN32 _fd = PR_Open(name, PRmode, PRmode); #else _fd = PR_Open(name, PRmode, flags); #endif if (_fd == 0) return 0; _opened = PR_TRUE; if ((!unbuffered()) && (!ebuf())){ char * sbuf = new char[STRM_BUFSIZ]; if (!sbuf) unbuffered(1); else{ _allocated = PR_TRUE; streambuf::setb(sbuf,sbuf+STRM_BUFSIZ,0); } } if (mode & ios::ate){ if (seekoff(0,ios::end,mode)==EOF){ close(); return 0; } } return this; }
int stdiobuf::underflow() { /*************************/ // Handle allocating a buffer, if required. // Handle filling the get area of the streambuf. // Read more stuff from the input device. // Return the first character read. char *ptr; int len; __lock_it( __b_lock ); // Flush any output waiting in the buffer: if( out_waiting() > 0 ) { if( sync() == EOF ) { return( EOF ); } } // discard put area setp( NULL, NULL ); // Try to allocate a buffer: if( base() == NULL ) { if( allocate() == EOF ) { return( EOF ); } if( base() == NULL ) { // unbuffered special case ptr = __unbuffered_get_area + DEFAULT_PUTBACK_SIZE; setg( __unbuffered_get_area, ptr, ptr ); int ch; ch = fgetc( __file_pointer ); if( ch == EOF ) { return( EOF ); } else { *egptr() = (char)ch; } setg( eback(), gptr(), egptr() + 1 ); return( *gptr() ); } else { ptr = base() + DEFAULT_PUTBACK_SIZE; setg( base(), ptr, ptr ); } } else if( gptr() >= egptr() ) { ptr = base() + DEFAULT_PUTBACK_SIZE; setg( base(), ptr, ptr ); } len = (__huge_ptr_int)(ebuf() - egptr()); if( len > 0 ) { len = 1; int ch; ch = fgetc( __file_pointer ); if( ch == EOF ) { return( EOF ); } else { *egptr() = (char)ch; } } else { len = 0; } setg( eback(), gptr(), egptr() + len ); return( gptr() < egptr() ? *gptr() : EOF ); }