diff -r 2fe1408b6811 -r e1b950c65cb4 epoc32/include/stdapis/stlportv5/stl/_sstream.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/epoc32/include/stdapis/stlportv5/stl/_sstream.c Wed Mar 31 12:27:01 2010 +0100 @@ -0,0 +1,671 @@ +/* + * © Portions copyright (c) 2006-2007 Nokia Corporation. All rights reserved. + * Copyright (c) 1999 + * Silicon Graphics Computer Systems, Inc. + * + * Copyright (c) 1999 + * Boris Fomitchev + * + * This material is provided "as is", with absolutely no warranty expressed + * or implied. Any use is at your own risk. + * + * Permission to use or copy this software for any purpose is hereby granted + * without fee, provided the above notices are retained on all copies. + * Permission to modify the code and to distribute modified code is granted, + * provided the above notices are retained, and a notice that the code was + * modified is included with the above copyright notice. + * + */ + +#ifndef _STLP_SSTREAM_C +#define _STLP_SSTREAM_C + +#ifndef _STLP_SSTREAM_H +# include +#include +#endif + +# if defined (_STLP_EXPOSE_STREAM_IMPLEMENTATION) + +# if defined ( _STLP_NESTED_TYPE_PARAM_BUG ) +// no wint_t is supported for this mode +# define __BSB_int_type__ int +# define __BSB_pos_type__ streampos +# else +# define __BSB_int_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_stringbuf<_CharT, _Traits, _Alloc>::int_type +# define __BSB_pos_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type +# endif + +_STLP_BEGIN_NAMESPACE + +//---------------------------------------------------------------------- +// Non-inline stringbuf member functions. + +// Constructors. Note that the base class constructor sets all of the +// get and area pointers to null. + +template +_STLP_EXP_DECLSPEC basic_stringbuf<_CharT, _Traits, _Alloc> + ::basic_stringbuf(ios_base::openmode __mode) + : basic_streambuf<_CharT, _Traits>(), _M_mode(__mode), _M_str() +{ +#ifdef __SYMBIAN32__ +if (_M_mode & ios_base::out) { + if (_M_mode & (ios_base::app | ios_base::ate)) + //increment the streampos to reflect the current streampos while writing + _M_str._M_stream_pos += _M_str.size(); +} +#endif +} + +template +_STLP_EXP_DECLSPEC basic_stringbuf<_CharT, _Traits, _Alloc> + ::basic_stringbuf(const basic_string<_CharT, _Traits, _Alloc>& __s, ios_base::openmode __mode) + : basic_streambuf<_CharT, _Traits>(), _M_mode(__mode), _M_str(__s) +{ +#ifdef __SYMBIAN32__ +if (_M_mode & ios_base::out) { + if (_M_mode & (ios_base::app | ios_base::ate)) + //increment the streampos to reflect the current streampos while writing + _M_str._M_stream_pos += _M_str.size(); +} +#endif + _M_set_ptrs(); +} + +template +_STLP_EXP_DECLSPEC basic_stringbuf<_CharT, _Traits, _Alloc>::~basic_stringbuf() +{} + +// Set the underlying string to a new value. +template +_STLP_EXP_DECLSPEC void +basic_stringbuf<_CharT, _Traits, _Alloc>::str(const basic_string<_CharT, _Traits, _Alloc>& __s) +{ + _M_str = __s; + _M_set_ptrs(); +} + +template +void +basic_stringbuf<_CharT, _Traits, _Alloc>::_M_set_ptrs() { + _CharT* __data_ptr = __CONST_CAST(_CharT*,_M_str.data()); + _CharT* __data_end = __data_ptr + _M_str.size(); + // The initial read position is the beginning of the string. + if (_M_mode & ios_base::in) { + if (_M_mode & ios_base::ate) + this->setg(__data_ptr, __data_end, __data_end); + else + this->setg(__data_ptr, __data_ptr, __data_end); + } + + // The initial write position is the beginning of the string. + if (_M_mode & ios_base::out) { + if (_M_mode & (ios_base::app | ios_base::ate)) + this->setp(__data_end, __data_end); + else + this->setp(__data_ptr, __data_end); + } +} + +// Precondition: gptr() >= egptr(). Returns a character, if one is available. +template +_STLP_EXP_DECLSPEC __BSB_int_type__ +basic_stringbuf<_CharT, _Traits, _Alloc>::underflow() +{ + return this->gptr() != this->egptr() + ? _Traits::to_int_type(*this->gptr()) + : _Traits::eof(); +} + +// Precondition: gptr() >= egptr(). +template +_STLP_EXP_DECLSPEC __BSB_int_type__ +basic_stringbuf<_CharT, _Traits, _Alloc>::uflow() +{ + if (this->gptr() != this->egptr()) { + int_type __c = _Traits::to_int_type(*this->gptr()); + this->gbump(1); + return __c; + } + else + return _Traits::eof(); +} + +template +_STLP_EXP_DECLSPEC __BSB_int_type__ +basic_stringbuf<_CharT, _Traits, _Alloc>::pbackfail(int_type __c) +{ + if (this->gptr() != this->eback()) { + if (!_Traits::eq_int_type(__c, _Traits::eof())) { + +if (_Traits::eq(_Traits::to_char_type(__c), this->gptr()[-1]) + || _M_mode == (ios_base::in | ios_base::out)) { + this->gbump(-1); + *this->gptr() = _Traits::to_char_type(__c); + return _Traits::not_eof(__c); + } + else{ + return _Traits::eof(); + } + } + else { + this->gbump(-1); + return _Traits::not_eof(__c); + } + } + else + return _Traits::eof(); +} + +template +_STLP_EXP_DECLSPEC __BSB_int_type__ +basic_stringbuf<_CharT, _Traits, _Alloc>::overflow(int_type __c) +{ + // fbp : reverse order of "ifs" to pass Dietmar's test. + // Apparently, standard allows overflow with eof even for read-only streams. + if (!_Traits::eq_int_type(__c, _Traits::eof())) { + if (_M_mode & ios_base::out) { + if (!(_M_mode & ios_base::in)) { + // It's a write-only streambuf, so we can use special append buffer. + if (this->pptr() == this->epptr()) + this->_M_append_buffer(); + + if (this->pptr() != this->epptr()) { + *this->pptr() = _Traits::to_char_type(__c); + this->pbump(1); + return __c; + } + else + return _Traits::eof(); + } + + else { + // We're not using a special append buffer, just the string itself. + if (this->pptr() == this->epptr()) { + ptrdiff_t __offset = this->gptr() - this->eback(); + _M_str.push_back(_Traits::to_char_type(__c)); + + _CharT* __data_ptr = __CONST_CAST(_CharT*,_M_str.data()); + size_t __data_size = _M_str.size(); + + this->setg(__data_ptr, __data_ptr + __offset, __data_ptr+__data_size); + this->setp(__data_ptr, __data_ptr + __data_size); + this->pbump((int)__data_size); + return __c; + } + else { + *this->pptr() = _Traits::to_char_type(__c); + this->pbump(1); + return __c; + } + } + } + else // Overflow always fails if it's read-only + return _Traits::eof(); + } + else // __c is EOF, so we don't have to do anything + return _Traits::not_eof(__c); +} + +template +_STLP_EXP_DECLSPEC streamsize +basic_stringbuf<_CharT, _Traits, _Alloc>::xsputn(const char_type* __s, + streamsize __n) +{ + streamsize __nwritten = 0; + + if ((_M_mode & ios_base::out) && __n > 0) { + // If the put pointer is somewhere in the middle of the string, + // then overwrite instead of append. + if (this->pbase() == _M_str.data() ) { + ptrdiff_t __avail = _M_str.data() + _M_str.size() - this->pptr(); + if (__avail > __n) { + _Traits::copy(this->pptr(), __s, __n); + this->pbump((int)__n); +#ifdef __SYMBIAN32__ + // _M_str._M_stream_pos += __n; //increment streampos to number of characters in stream +#endif + return __n; + } + else { + _Traits::copy(this->pptr(), __s, __avail); + __nwritten += __avail; + __n -= __avail; + __s += __avail; +#ifdef __SYMBIAN32__ + // _M_str._M_stream_pos += __avail;//increment streampos to number of characters in stream +#endif + this->setp(_M_Buf, _M_Buf + __STATIC_CAST(int,_S_BufSiz)); + } + } + + // At this point we know we're appending. + if (_M_mode & ios_base::in) { + ptrdiff_t __get_offset = this->gptr() - this->eback(); + _M_str.append(__s, __s + __n); + + _CharT* __data_ptr = __CONST_CAST(_CharT*,_M_str.data()); + size_t __data_size = _M_str.size(); + + this->setg(__data_ptr, __data_ptr + __get_offset, __data_ptr+__data_size); + this->setp(__data_ptr, __data_ptr + __data_size); + this->pbump((int)__data_size); + } + else { + _M_append_buffer(); +#ifdef __SYMBIAN32__ + if (_M_str._M_stream_pos >= 0 + && (_M_str._M_stream_pos < _M_str.size())) { + if((_M_str.size() - _M_str._M_stream_pos) >= __n) + _M_str.replace(_M_str._M_stream_pos, __n, __s); + else + { + _M_str.replace(_M_str._M_stream_pos, (_M_str.size() - _M_str._M_stream_pos), __s); + _M_str.append(__s + (__n - (_M_str.size() - _M_str._M_stream_pos)), __s + __n); + } + } else { + _M_str.append(__s, __s + __n); + } + _M_str._M_stream_pos += __n; +#else //__SYMBIAN32__ + _M_str.append(__s, __s + __n); +#endif // __SYMBIAN32__ + } + __nwritten += __n; + } + + return __nwritten; +} + +template +streamsize +basic_stringbuf<_CharT, _Traits, _Alloc>::_M_xsputnc(char_type __c, + streamsize __n) +{ + streamsize __nwritten = 0; + + if ((_M_mode & ios_base::out) && __n > 0) { + // If the put pointer is somewhere in the middle of the string, + // then overwrite instead of append. + if (this->pbase() == _M_str.data()) { + ptrdiff_t __avail = _M_str.data() + _M_str.size() - this->pptr(); + if (__avail > __n) { + _Traits::assign(this->pptr(), __n, __c); + this->pbump((int)__n); + return __n; + } + else { + _Traits::assign(this->pptr(), __avail, __c); + __nwritten += __avail; + __n -= __avail; + this->setp(_M_Buf, _M_Buf + __STATIC_CAST(int,_S_BufSiz)); + } + } + + // At this point we know we're appending. + if (this->_M_mode & ios_base::in) { + ptrdiff_t __get_offset = this->gptr() - this->eback(); + _M_str.append(__n, __c); + + _CharT* __data_ptr = __CONST_CAST(_CharT*,_M_str.data()); + size_t __data_size = _M_str.size(); + + this->setg(__data_ptr, __data_ptr + __get_offset, __data_ptr+__data_size); + this->setp(__data_ptr, __data_ptr + __data_size); + this->pbump((int)__data_size); + + } + else { + _M_append_buffer(); +// _M_str.append(__n, __c); +#ifdef __SYMBIAN32__ + if (_M_str._M_stream_pos >= 0 + && (_M_str._M_stream_pos < _M_str.size())) { + if((_M_str.size() - _M_str._M_stream_pos) >= __n) + _M_str.replace(_M_str._M_stream_pos,__n, __n, __c); + else + { + _M_str.replace(_M_str._M_stream_pos, (_M_str.size() - _M_str._M_stream_pos), (_M_str.size() - _M_str._M_stream_pos), __c); + _M_str.append(__n, __c); + } + } else { + _M_str.append(__n, __c); + } + _M_str._M_stream_pos += __n; +#else //__SYMBIAN32__ + _M_str.append(__n, __c); +#endif // __SYMBIAN32__ + } + + __nwritten += __n; + } + + return __nwritten; +} + +// According to the C++ standard the effects of setbuf are implementation +// defined, except that setbuf(0, 0) has no effect. In this implementation, +// setbuf(, n), for n > 0, calls reserve(n) on the underlying +// string. +template +_STLP_EXP_DECLSPEC basic_streambuf<_CharT, _Traits>* +#ifdef __SYMBIAN32__ +basic_stringbuf<_CharT, _Traits, _Alloc>::setbuf(_CharT* __s, streamsize __n) +#else +basic_stringbuf<_CharT, _Traits, _Alloc>::setbuf(_CharT*, streamsize __n) +#endif //__SYMBIAN32__ +{ + if (__n > 0) { + bool __do_get_area = false; + bool __do_put_area = false; + ptrdiff_t __offg = 0; + ptrdiff_t __offp = 0; + + if (this->pbase() == _M_str.data()) { + __do_put_area = true; + __offp = this->pptr() - this->pbase(); + } + + if (this->eback() == _M_str.data()) { + __do_get_area = true; + __offg = this->gptr() - this->eback(); + } + + if ((_M_mode & ios_base::out) && !(_M_mode & ios_base::in)) + _M_append_buffer(); + + _M_str.reserve(__n); + + _CharT* __data_ptr = __CONST_CAST(_CharT*,_M_str.data()); +#ifdef __SYMBIAN32__ + size_t __data_size = __n; + memmove(__data_ptr, __s, __n*sizeof(_CharT)); + _M_str._M_start = __data_ptr; + _M_str._M_finish = __data_ptr+__n; +#else + size_t __data_size = _M_str.size(); +#endif //__SYMBIAN32__ + + if (__do_get_area) { +#ifdef __SYMBIAN32__ + this->setg(__data_ptr, __data_ptr, __data_ptr+__data_size); +#else + this->setg(__data_ptr, __data_ptr + __offg, __data_ptr+__data_size); +#endif //__SYMBIAN32__ + } + + if (__do_put_area) { + this->setp(__data_ptr, __data_ptr+__data_size); +#ifndef __SYMBIAN32__ + this->pbump((int)__offp); +#endif //__SYMBIAN32__ + } + } + + return this; +} + +template +_STLP_EXP_DECLSPEC __BSB_pos_type__ +basic_stringbuf<_CharT, _Traits, _Alloc>::seekoff(off_type __off, + ios_base::seekdir __dir, + ios_base::openmode __mode) +{ + bool __stl_in = false; + bool __stl_out = false; + + if ((__mode & (ios_base::in | ios_base::out)) == (ios_base::in | ios_base::out) ) { + if (__dir == ios_base::beg || __dir == ios_base::end) + __stl_in = __stl_out = true; + } + else if (__mode & ios_base::in) + __stl_in = true; + else if (__mode & ios_base::out) + __stl_out = true; + + if (!__stl_in && !__stl_out) + return pos_type(off_type(-1)); + else if ((__stl_in && (!(_M_mode & ios_base::in) || this->gptr() == 0)) || + (__stl_out && (!(_M_mode & ios_base::out) || this->pptr() == 0))) + return pos_type(off_type(-1)); + +#ifdef __SYMBIAN32__ + if (_M_mode & ios_base::out) +#else + if ((_M_mode & ios_base::out) && !(_M_mode & ios_base::in)) +#endif + _M_append_buffer(); + + streamoff __newoff; + switch(__dir) { + case ios_base::beg: + __newoff = 0; + break; + case ios_base::end: + __newoff = _M_str.size(); + break; + case ios_base::cur: + __newoff = __stl_in ? this->gptr() - this->eback() +#ifdef __SYMBIAN32__ + : ((this->pbase() != this->_M_str) ? _M_str._M_stream_pos + : this->pptr() - this->pbase()); +#else + : this->pptr() - this->pbase(); +#endif //__SYMBIAN32__ + break; + default: + return pos_type(off_type(-1)); + } + + __off += __newoff; + + if (__stl_in) { + ptrdiff_t __n = this->egptr() - this->eback(); + + if (__off < 0 || __off > __n) + return pos_type(off_type(-1)); + else + this->setg(this->eback(), this->eback() + __off, this->eback() + __n); + } + + if (__stl_out) { + ptrdiff_t __n; +#ifdef __SYMBIAN32__ + //if (this->pbase() != this->_M_str) { + void* __data_ptr1 = reinterpret_cast(this->pbase()); + _CharT* __data_ptr2 = __CONST_CAST(_CharT*,this->_M_str.data()); + + if (__data_ptr1 != __data_ptr2) { + __n = _M_str.size(); + } else { +#endif // __SYMBIAN32__ + __n = this->epptr() - this->pbase(); +#ifdef __SYMBIAN32__ + } +#endif //__SYMBIAN32__ + if (__off < 0 || __off > __n) + return pos_type(off_type(-1)); + else { +#ifdef __SYMBIAN32__ + void* __data_ptr1 = reinterpret_cast(this->pbase()); + _CharT* __data_ptr2 = __CONST_CAST(_CharT*,this->_M_str.data()); + + if (__data_ptr1 != __data_ptr2) { + _M_str._M_stream_pos = __off; + } else { +#endif //__SYMBIAN32__ + this->setp(this->pbase(), this->pbase() + __n); + this->pbump((int)__off); +#ifdef __SYMBIAN32__ + } +#endif // __SYMBIAN32__ + } + } + + return pos_type(__off); +} + +template +_STLP_EXP_DECLSPEC __BSB_pos_type__ +basic_stringbuf<_CharT, _Traits, _Alloc> + ::seekpos(pos_type __pos, ios_base::openmode __mode) +{ + bool __stl_in = (__mode & ios_base::in) != 0; + bool __stl_out = (__mode & ios_base::out) != 0; + + if ((__stl_in && (!(_M_mode & ios_base::in) || this->gptr() == 0)) || + (__stl_out && (!(_M_mode & ios_base::out) || this->pptr() == 0)) || + (!__stl_in && !__stl_out)) + return pos_type(off_type(-1)); + + const off_type __n = __pos - pos_type(off_type(0)); + if ((_M_mode & ios_base::out) && !(_M_mode & ios_base::in)) + _M_append_buffer(); + + if (__stl_in) { + if (__n < 0 || __n > this->egptr() - this->eback()) + return pos_type(off_type(-1)); + this->setg(this->eback(), this->eback() + __n, this->egptr()); + } + + if (__stl_out) { + if (__n < 0 || size_t(__n) > _M_str.size()) + return pos_type(off_type(-1)); + + _CharT* __data_ptr = __CONST_CAST(_CharT*,_M_str.data()); + size_t __data_size = _M_str.size(); + + this->setp(__data_ptr, __data_ptr+__data_size); + this->pbump((int)__n); + } + + return __pos; +} + +// This is declared as a const member function because it is +// called by basic_stringbuf<>::str(). Precondition: this is a +// write-only stringbuf. We can't use an output buffer for read- +// write stringbufs. Postcondition: pptr is reset to the beginning +// of the buffer. +template +void basic_stringbuf<_CharT, _Traits, _Alloc>::_M_append_buffer() const + +{ + // Do we have a buffer to append? + if (this->pbase() == this->_M_Buf && this->pptr() != this->_M_Buf) { + basic_stringbuf<_CharT, _Traits, _Alloc>* __this = __CONST_CAST(_Self*,this); +#ifdef __SYMBIAN32__ + size_t __n = this->pptr() - this->pbase(); + if (__this->_M_str._M_stream_pos >= 0 + && (__this->_M_str._M_stream_pos != __this->_M_str.size())) { + { + *(this->pptr()) = (_CharT)0; +#ifdef __SYMBIAN32__ + __this->_M_str.replace(_M_str._M_stream_pos, __n, (const _CharT*)this->pbase(), (const _CharT*)this->pptr()-(const _CharT*)this->pbase()); +#else + __this->_M_str.replace(_M_str._M_stream_pos, __n, (const _CharT*)this->pbase()); + +#endif + } + } else { + __this->_M_str.append((const _CharT*)this->pbase(), (const _CharT*)this->pptr()); + } + __this->_M_str._M_stream_pos += __n; +#else // __SYMBAIN32__ + __this->_M_str.append((const _CharT*)this->pbase(), (const _CharT*)this->pptr()); +#endif // __SYMBIAN32__ + __this->setp(__CONST_CAST(_CharT*,_M_Buf), + __CONST_CAST(_CharT*,_M_Buf + __STATIC_CAST(int,_S_BufSiz))); + } + + // Have we run off the end of the string? + else if (this->pptr() == this->epptr()) { + basic_stringbuf<_CharT, _Traits, _Alloc>* __this = __CONST_CAST(_Self*,this); + __this->setp(__CONST_CAST(_CharT*,_M_Buf), + __CONST_CAST(_CharT*,_M_Buf + __STATIC_CAST(int,_S_BufSiz))); + __this->_M_str._M_stream_pos = __this->_M_str._M_finish - __this->_M_str._M_start; + } +} + +//---------------------------------------------------------------------- +// Non-inline istringstream member functions. + +template +basic_istringstream<_CharT, _Traits, _Alloc> + ::basic_istringstream(ios_base::openmode __mode) + : basic_istream<_CharT, _Traits>(0), + _M_buf(__mode | ios_base::in) +{ + this->init(&_M_buf); +} + +template +basic_istringstream<_CharT, _Traits, _Alloc> + ::basic_istringstream(const _String& __str,ios_base::openmode __mode) + : basic_istream<_CharT, _Traits>(0), + _M_buf(__str, __mode | ios_base::in) +{ + this->init(&_M_buf); +} + +template +basic_istringstream<_CharT, _Traits, _Alloc>::~basic_istringstream() +{} + +//---------------------------------------------------------------------- +// Non-inline ostringstream member functions. + +template +basic_ostringstream<_CharT, _Traits, _Alloc> + ::basic_ostringstream(ios_base::openmode __mode) + : basic_ostream<_CharT, _Traits>(0), + _M_buf(__mode | ios_base::out) +{ + this->init(&_M_buf); +} + +template +basic_ostringstream<_CharT, _Traits, _Alloc> + ::basic_ostringstream(const _String& __str, ios_base::openmode __mode) + : basic_ostream<_CharT, _Traits>(0), + _M_buf(__str, __mode | ios_base::out) +{ + this->init(&_M_buf); +} + +template +basic_ostringstream<_CharT, _Traits, _Alloc>::~basic_ostringstream() +{} + +//---------------------------------------------------------------------- +// Non-inline stringstream member functions. + +template +_STLP_EXP_DECLSPEC basic_stringstream<_CharT, _Traits, _Alloc> + ::basic_stringstream(ios_base::openmode __mode) + : basic_iostream<_CharT, _Traits>(0), _M_buf(__mode) +{ + this->init(&_M_buf); +} + +template +_STLP_EXP_DECLSPEC basic_stringstream<_CharT, _Traits, _Alloc> + ::basic_stringstream(const _String& __str, ios_base::openmode __mode) + : basic_iostream<_CharT, _Traits>(0), _M_buf(__str, __mode) +{ + this->init(&_M_buf); +} + +template +basic_stringstream<_CharT, _Traits, _Alloc>::~basic_stringstream() +{} + +_STLP_END_NAMESPACE + +# undef __BSB_int_type__ +# undef __BSB_pos_type__ + +# endif /* EXPOSE */ + +#endif /* _STLP_SSTREAM_C */