Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:45:32

0001 // ----------------------------------------------------------------------------
0002 //  alt_sstream_impl.hpp : alternative stringstream, templates implementation 
0003 // ----------------------------------------------------------------------------
0004 
0005 //  Copyright Samuel Krempp 2003. Use, modification, and distribution are
0006 //  subject to the Boost Software License, Version 1.0. (See accompanying
0007 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0008 
0009 //  See http://www.boost.org/libs/format for library home page
0010 
0011 // ----------------------------------------------------------------------------
0012 
0013 #ifndef BOOST_SK_ALT_SSTREAM_IMPL_HPP
0014 #define BOOST_SK_ALT_SSTREAM_IMPL_HPP
0015 
0016 namespace boost {
0017     namespace io {
0018 // --- Implementation  ------------------------------------------------------//
0019 
0020         template<class Ch, class Tr, class Alloc>
0021         void basic_altstringbuf<Ch, Tr, Alloc>:: 
0022         clear_buffer () {
0023             const Ch * p = pptr();
0024             const Ch * b = pbase();
0025             if(p != NULL && p != b) {
0026                 seekpos(0, ::std::ios_base::out); 
0027             }
0028             p = gptr();
0029             b = eback();
0030             if(p != NULL && p != b) {
0031                 seekpos(0, ::std::ios_base::in); 
0032             }
0033         }
0034 
0035         template<class Ch, class Tr, class Alloc>
0036         void basic_altstringbuf<Ch, Tr, Alloc>:: 
0037         str (const string_type& s) {
0038             size_type sz=s.size();
0039             if(sz != 0 && mode_ & (::std::ios_base::in | ::std::ios_base::out) ) {
0040 #ifdef _RWSTD_NO_CLASS_PARTIAL_SPEC
0041                 void *vd_ptr = boost::allocator_allocate(alloc_, sz, is_allocated_? eback() : 0);
0042                 Ch *new_ptr = static_cast<Ch *>(vd_ptr);
0043 #else
0044                 Ch *new_ptr = boost::allocator_allocate(alloc_, sz, is_allocated_? eback() : 0);
0045 #endif
0046                 // if this didnt throw, we're safe, update the buffer
0047                 dealloc();
0048                 sz = s.copy(new_ptr, sz);
0049                 putend_ = new_ptr + sz;
0050                 if(mode_ & ::std::ios_base::in)
0051                     streambuf_t::setg(new_ptr, new_ptr, new_ptr + sz);
0052                 if(mode_ & ::std::ios_base::out) {
0053                     streambuf_t::setp(new_ptr, new_ptr + sz);
0054                     if(mode_ & (::std::ios_base::app | ::std::ios_base::ate))
0055                         streambuf_t::pbump(static_cast<int>(sz));
0056                     if(gptr() == NULL)
0057                         streambuf_t::setg(new_ptr, NULL, new_ptr);
0058                 }
0059                 is_allocated_ = true;
0060             }
0061             else 
0062                 dealloc();
0063         }
0064         template<class Ch, class Tr, class Alloc>
0065         Ch*   basic_altstringbuf<Ch, Tr, Alloc>:: 
0066         begin () const {
0067             if(mode_ & ::std::ios_base::out && pptr() != NULL)
0068                 return pbase();
0069             else if(mode_ & ::std::ios_base::in && gptr() != NULL)
0070                 return eback();
0071             return NULL;
0072         }
0073 
0074         template<class Ch, class Tr, class Alloc>
0075         typename std::basic_string<Ch,Tr,Alloc>::size_type
0076         basic_altstringbuf<Ch, Tr, Alloc>:: 
0077         size () const { 
0078             if(mode_ & ::std::ios_base::out && pptr())
0079                 return static_cast<size_type>(pend() - pbase());
0080             else if(mode_ & ::std::ios_base::in && gptr())
0081                 return static_cast<size_type>(egptr() - eback());
0082             else 
0083                 return 0;
0084         }
0085 
0086         template<class Ch, class Tr, class Alloc>
0087         typename std::basic_string<Ch,Tr,Alloc>::size_type
0088         basic_altstringbuf<Ch, Tr, Alloc>:: 
0089         cur_size () const { 
0090             if(mode_ & ::std::ios_base::out && pptr())
0091                 return static_cast<streamsize>( pptr() - pbase());
0092             else if(mode_ & ::std::ios_base::in && gptr())
0093                 return static_cast<streamsize>( gptr() - eback());
0094             else 
0095                 return 0;
0096         }
0097 
0098         template<class Ch, class Tr, class Alloc>
0099         typename basic_altstringbuf<Ch, Tr, Alloc>::pos_type  
0100         basic_altstringbuf<Ch, Tr, Alloc>:: 
0101         seekoff (off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which) {
0102             if(pptr() != NULL && putend_ < pptr())
0103                 putend_ = pptr();
0104             if(which & ::std::ios_base::in && gptr() != NULL) {
0105                 // get area
0106                 if(way == ::std::ios_base::end)
0107                     off += static_cast<off_type>(putend_ - gptr());
0108                 else if(way == ::std::ios_base::beg)
0109                     off += static_cast<off_type>(eback() - gptr());
0110                 else if(way != ::std::ios_base::cur || (which & ::std::ios_base::out) )
0111                     // (altering in&out is only supported if way is beg or end, not cur)
0112                     return pos_type(off_type(-1));
0113                 if(eback() <= off+gptr() && off+gptr() <= putend_ ) {
0114                     // set gptr
0115                     streambuf_t::gbump(static_cast<int>(off));
0116                     if(which & ::std::ios_base::out && pptr() != NULL)
0117                         // update pptr to match gptr
0118                         streambuf_t::pbump(static_cast<int>(gptr()-pptr()));
0119                 }
0120                 else
0121                     off = off_type(-1);
0122             }
0123             else if(which & ::std::ios_base::out && pptr() != NULL) {
0124                 // put area
0125                 if(way == ::std::ios_base::end)
0126                     off += static_cast<off_type>(putend_ - pptr());
0127                 else if(way == ::std::ios_base::beg)
0128                     off += static_cast<off_type>(pbase() - pptr());
0129                 else
0130                     return pos_type(off_type(-1));                    
0131                 if(pbase() <= off+pptr() && off+pptr() <= putend_)
0132                     // set pptr
0133                     streambuf_t::pbump(static_cast<int>(off)); 
0134                 else
0135                     off = off_type(-1);
0136             }
0137             else // neither in nor out
0138                 off = off_type(-1);
0139             return (pos_type(off));
0140         }
0141         //- end seekoff(..)
0142 
0143         
0144         template<class Ch, class Tr, class Alloc>
0145         typename basic_altstringbuf<Ch, Tr, Alloc>::pos_type 
0146         basic_altstringbuf<Ch, Tr, Alloc>:: 
0147         seekpos (pos_type pos, ::std::ios_base::openmode which) {
0148             off_type off = off_type(pos); // operation guaranteed by fpos.operations table 127
0149             if(pptr() != NULL && putend_ < pptr())
0150                 putend_ = pptr();
0151             if(off != off_type(-1)) {
0152                 if(which & ::std::ios_base::in && gptr() != NULL) {
0153                     // get area
0154                     if(0 <= off && off <= putend_ - eback()) {
0155                         streambuf_t::gbump(static_cast<int>(eback() - gptr() + off));
0156                         if(which & ::std::ios_base::out && pptr() != NULL) {
0157                             // update pptr to match gptr
0158                             streambuf_t::pbump(static_cast<int>(gptr()-pptr()));
0159                         }
0160                     }
0161                     else
0162                         off = off_type(-1);
0163                 }
0164                 else if(which & ::std::ios_base::out && pptr() != NULL) {
0165                     // put area
0166                     if(0 <= off && off <= putend_ - eback())
0167                         streambuf_t::pbump(static_cast<int>(eback() - pptr() + off));
0168                     else
0169                         off = off_type(-1);
0170                 }
0171                 else // neither in nor out
0172                     off = off_type(-1);
0173                 return (pos_type(off));
0174             }
0175             else {
0176                 BOOST_ASSERT(0); // fpos.operations allows undefined-behaviour here
0177                 return pos_type(off_type(-1));
0178             }
0179         }
0180         // -end seekpos(..)
0181 
0182 
0183         template<class Ch, class Tr, class Alloc>
0184         typename basic_altstringbuf<Ch, Tr, Alloc>::int_type
0185         basic_altstringbuf<Ch, Tr, Alloc>:: 
0186         underflow () {
0187             if(gptr() == NULL) // no get area -> nothing to get.
0188                 return (compat_traits_type::eof()); 
0189             else if(gptr() < egptr())  // ok, in buffer
0190                 return (compat_traits_type::to_int_type(*gptr())); 
0191             else if(mode_ & ::std::ios_base::in && pptr() != NULL
0192                     && (gptr() < pptr() || gptr() < putend_) )
0193                 {  // expand get area 
0194                     if(putend_ < pptr()) 
0195                         putend_ = pptr(); // remember pptr reached this far
0196                     streambuf_t::setg(eback(), gptr(), putend_);
0197                     return (compat_traits_type::to_int_type(*gptr()));
0198                 }
0199             else // couldnt get anything. EOF.
0200                 return (compat_traits_type::eof());
0201         }
0202         // -end underflow(..)
0203 
0204 
0205         template<class Ch, class Tr, class Alloc>
0206         typename basic_altstringbuf<Ch, Tr, Alloc>::int_type 
0207         basic_altstringbuf<Ch, Tr, Alloc>:: 
0208         pbackfail (int_type meta) {
0209             if(gptr() != NULL  &&  (eback() < gptr()) 
0210                && (mode_ & (::std::ios_base::out)
0211                    || compat_traits_type::eq_int_type(compat_traits_type::eof(), meta)
0212                    || compat_traits_type::eq(compat_traits_type::to_char_type(meta), gptr()[-1]) ) ) { 
0213                 streambuf_t::gbump(-1); // back one character
0214                 if(!compat_traits_type::eq_int_type(compat_traits_type::eof(), meta))
0215                     //  put-back meta into get area
0216                     *gptr() = compat_traits_type::to_char_type(meta);
0217                 return (compat_traits_type::not_eof(meta));
0218             }
0219             else
0220                 return (compat_traits_type::eof());  // failed putback
0221         }
0222         // -end pbackfail(..)
0223 
0224 
0225         template<class Ch, class Tr, class Alloc>
0226         typename basic_altstringbuf<Ch, Tr, Alloc>::int_type 
0227         basic_altstringbuf<Ch, Tr, Alloc>:: 
0228         overflow (int_type meta) {
0229 #ifdef BOOST_MSVC
0230 #pragma warning(push)
0231 #pragma warning(disable:4996)
0232 #endif
0233             if(compat_traits_type::eq_int_type(compat_traits_type::eof(), meta))
0234                 return compat_traits_type::not_eof(meta); // nothing to do
0235             else if(pptr() != NULL && pptr() < epptr()) {
0236                 streambuf_t::sputc(compat_traits_type::to_char_type(meta));
0237                 return meta;
0238             }
0239             else if(! (mode_ & ::std::ios_base::out)) 
0240                 // no write position, and cant make one
0241                 return compat_traits_type::eof(); 
0242             else { // make a write position available
0243                 std::size_t prev_size = pptr() == NULL ? 0 : epptr() - eback();
0244                 std::size_t new_size = prev_size;
0245                 // exponential growth : size *= 1.5
0246                 std::size_t add_size = new_size / 2;
0247                 if(add_size < alloc_min)
0248                     add_size = alloc_min;
0249                 Ch * newptr = NULL,  *oldptr = eback();
0250 
0251                 // make sure adding add_size wont overflow size_t
0252                 while (0 < add_size && ((std::numeric_limits<std::size_t>::max)()
0253                                         - add_size < new_size) )
0254                     add_size /= 2;
0255                 if(0 < add_size) {
0256                     new_size += add_size;
0257 #ifdef _RWSTD_NO_CLASS_PARTIAL_SPEC
0258                     void *vdptr = boost::allocator_allocate(alloc_, new_size, is_allocated_? oldptr : 0);
0259                     newptr = static_cast<Ch *>(vdptr);
0260 #else
0261                     newptr = boost::allocator_allocate(alloc_, new_size, is_allocated_? oldptr : 0);
0262 #endif
0263                 }
0264 
0265                 if(0 < prev_size)
0266                     compat_traits_type::copy(newptr, oldptr, prev_size);
0267                 if(is_allocated_)
0268                     alloc_.deallocate(oldptr, prev_size);
0269                 is_allocated_=true;
0270 
0271                 if(prev_size == 0) { // first allocation
0272                     putend_ = newptr;
0273                     streambuf_t::setp(newptr, newptr + new_size);
0274                     if(mode_ & ::std::ios_base::in)
0275                         streambuf_t::setg(newptr, newptr, newptr + 1);
0276                     else
0277                         streambuf_t::setg(newptr, 0, newptr);
0278                 }
0279                 else { // update pointers
0280                     putend_ = putend_ - oldptr + newptr;
0281                     int pptr_count = static_cast<int>(pptr()-pbase());
0282                     int gptr_count = static_cast<int>(gptr()-eback());
0283                     streambuf_t::setp(pbase() - oldptr + newptr, newptr + new_size);
0284                     streambuf_t::pbump(pptr_count);
0285                     if(mode_ & ::std::ios_base::in)
0286                         streambuf_t::setg(newptr, newptr + gptr_count, pptr() + 1);
0287                     else
0288                         streambuf_t::setg(newptr, 0, newptr);
0289                 }
0290                 streambuf_t::sputc(compat_traits_type::to_char_type(meta));
0291                 return meta;
0292             }
0293 #ifdef BOOST_MSVC
0294 #pragma warning(pop)
0295 #endif
0296         }
0297         // -end overflow(..)
0298 
0299         template<class Ch, class Tr, class Alloc>
0300         void basic_altstringbuf<Ch, Tr, Alloc>:: dealloc() {
0301             if(is_allocated_)
0302                 alloc_.deallocate(eback(), (pptr() != NULL ? epptr() : egptr()) - eback());
0303             is_allocated_ = false;
0304             streambuf_t::setg(0, 0, 0);
0305             streambuf_t::setp(0, 0);
0306             putend_ = NULL;
0307         }
0308 
0309     }// N.S. io
0310 } // N.S. boost
0311 
0312 #endif // include guard
0313