PageRenderTime 116ms CodeModel.GetById 20ms app.highlight 86ms RepoModel.GetById 2ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/format/alt_sstream_impl.hpp

http://hadesmem.googlecode.com/
C++ Header | 313 lines | 260 code | 25 blank | 28 comment | 133 complexity | bbced7535e06f8106532fdcb0349cf44 MD5 | raw file
  1// ----------------------------------------------------------------------------
  2//  alt_sstream_impl.hpp : alternative stringstream, templates implementation 
  3// ----------------------------------------------------------------------------
  4
  5//  Copyright Samuel Krempp 2003. Use, modification, and distribution are
  6//  subject to the Boost Software License, Version 1.0. (See accompanying
  7//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  8
  9//  See http://www.boost.org/libs/format for library home page
 10
 11// ----------------------------------------------------------------------------
 12
 13#ifndef BOOST_SK_ALT_SSTREAM_IMPL_HPP
 14#define BOOST_SK_ALT_SSTREAM_IMPL_HPP
 15
 16namespace boost {
 17    namespace io {
 18// --- Implementation  ------------------------------------------------------//
 19
 20        template<class Ch, class Tr, class Alloc>
 21        void basic_altstringbuf<Ch, Tr, Alloc>:: 
 22        clear_buffer () {
 23            const Ch * p = pptr();
 24            const Ch * b = pbase();
 25            if(p != NULL && p != b) {
 26                seekpos(0, ::std::ios_base::out); 
 27            }
 28            p = gptr();
 29            b = eback();
 30            if(p != NULL && p != b) {
 31                seekpos(0, ::std::ios_base::in); 
 32            }
 33        }
 34
 35        template<class Ch, class Tr, class Alloc>
 36        void basic_altstringbuf<Ch, Tr, Alloc>:: 
 37        str (const string_type& s) {
 38            size_type sz=s.size();
 39            if(sz != 0 && mode_ & (::std::ios_base::in | ::std::ios_base::out) ) {
 40#ifdef _RWSTD_NO_CLASS_PARTIAL_SPEC
 41                void *vd_ptr = alloc_.allocate(sz, is_allocated_? eback() : 0);
 42                Ch *new_ptr = static_cast<Ch *>(vd_ptr);
 43#else
 44                Ch *new_ptr = alloc_.allocate(sz, is_allocated_? eback() : 0);
 45#endif
 46                // if this didnt throw, we're safe, update the buffer
 47                dealloc();
 48                sz = s.copy(new_ptr, sz);
 49                putend_ = new_ptr + sz;
 50                if(mode_ & ::std::ios_base::in)
 51                    streambuf_t::setg(new_ptr, new_ptr, new_ptr + sz);
 52                if(mode_ & ::std::ios_base::out) {
 53                    streambuf_t::setp(new_ptr, new_ptr + sz);
 54                    if(mode_ & (::std::ios_base::app | ::std::ios_base::ate))
 55                        streambuf_t::pbump(static_cast<int>(sz));
 56                    if(gptr() == NULL)
 57                        streambuf_t::setg(new_ptr, NULL, new_ptr);
 58                }
 59                is_allocated_ = true;
 60            }
 61            else 
 62                dealloc();
 63        }
 64        template<class Ch, class Tr, class Alloc>
 65        Ch*   basic_altstringbuf<Ch, Tr, Alloc>:: 
 66        begin () const {
 67            if(mode_ & ::std::ios_base::out && pptr() != NULL)
 68                return pbase();
 69            else if(mode_ & ::std::ios_base::in && gptr() != NULL)
 70                return eback();
 71            return NULL;
 72        }
 73
 74        template<class Ch, class Tr, class Alloc>
 75        typename std::basic_string<Ch,Tr,Alloc>::size_type
 76        basic_altstringbuf<Ch, Tr, Alloc>:: 
 77        size () const { 
 78            if(mode_ & ::std::ios_base::out && pptr())
 79                return static_cast<size_type>(pend() - pbase());
 80            else if(mode_ & ::std::ios_base::in && gptr())
 81                return static_cast<size_type>(egptr() - eback());
 82            else 
 83                return 0;
 84        }
 85
 86        template<class Ch, class Tr, class Alloc>
 87        typename std::basic_string<Ch,Tr,Alloc>::size_type
 88        basic_altstringbuf<Ch, Tr, Alloc>:: 
 89        cur_size () const { 
 90            if(mode_ & ::std::ios_base::out && pptr())
 91                return static_cast<streamsize>( pptr() - pbase());
 92            else if(mode_ & ::std::ios_base::in && gptr())
 93                return static_cast<streamsize>( gptr() - eback());
 94            else 
 95                return 0;
 96        }
 97
 98        template<class Ch, class Tr, class Alloc>
 99        typename basic_altstringbuf<Ch, Tr, Alloc>::pos_type  
100        basic_altstringbuf<Ch, Tr, Alloc>:: 
101        seekoff (off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which) {
102            if(pptr() != NULL && putend_ < pptr())
103                putend_ = pptr();
104            if(which & ::std::ios_base::in && gptr() != NULL) {
105                // get area
106                if(way == ::std::ios_base::end)
107                    off += static_cast<off_type>(putend_ - gptr());
108                else if(way == ::std::ios_base::beg)
109                    off += static_cast<off_type>(eback() - gptr());
110                else if(way != ::std::ios_base::cur || (which & ::std::ios_base::out) )
111                    // (altering in&out is only supported if way is beg or end, not cur)
112                    return pos_type(off_type(-1));
113                if(eback() <= off+gptr() && off+gptr() <= putend_ ) {
114                    // set gptr
115                    streambuf_t::gbump(static_cast<int>(off));
116                    if(which & ::std::ios_base::out && pptr() != NULL)
117                        // update pptr to match gptr
118                        streambuf_t::pbump(static_cast<int>(gptr()-pptr()));
119                }
120                else
121                    off = off_type(-1);
122            }
123            else if(which & ::std::ios_base::out && pptr() != NULL) {
124                // put area
125                if(way == ::std::ios_base::end)
126                    off += static_cast<off_type>(putend_ - pptr());
127                else if(way == ::std::ios_base::beg)
128                    off += static_cast<off_type>(pbase() - pptr());
129                else if(way != ::std::ios_base::beg)
130                    return pos_type(off_type(-1));                    
131                if(pbase() <= off+pptr() && off+pptr() <= putend_)
132                    // set pptr
133                    streambuf_t::pbump(static_cast<int>(off)); 
134                else
135                    off = off_type(-1);
136            }
137            else // neither in nor out
138                off = off_type(-1);
139            return (pos_type(off));
140        }
141        //- end seekoff(..)
142
143        
144        template<class Ch, class Tr, class Alloc>
145        typename basic_altstringbuf<Ch, Tr, Alloc>::pos_type 
146        basic_altstringbuf<Ch, Tr, Alloc>:: 
147        seekpos (pos_type pos, ::std::ios_base::openmode which) {
148            off_type off = off_type(pos); // operation guaranteed by 27.4.3.2 table 88
149            if(pptr() != NULL && putend_ < pptr())
150                putend_ = pptr();
151            if(off != off_type(-1)) {
152                if(which & ::std::ios_base::in && gptr() != NULL) {
153                    // get area
154                    if(0 <= off && off <= putend_ - eback()) {
155                        streambuf_t::gbump(static_cast<int>(eback() - gptr() + off));
156                        if(which & ::std::ios_base::out && pptr() != NULL) {
157                            // update pptr to match gptr
158                            streambuf_t::pbump(static_cast<int>(gptr()-pptr()));
159                        }
160                    }
161                    else
162                        off = off_type(-1);
163                }
164                else if(which & ::std::ios_base::out && pptr() != NULL) {
165                    // put area
166                    if(0 <= off && off <= putend_ - eback())
167                        streambuf_t::pbump(static_cast<int>(eback() - pptr() + off));
168                    else
169                        off = off_type(-1);
170                }
171                else // neither in nor out
172                    off = off_type(-1);
173                return (pos_type(off));
174            }
175            else {
176                BOOST_ASSERT(0); // ยง27.4.3.2 allows undefined-behaviour here
177                return pos_type(off_type(-1));
178            }
179        }
180        // -end seekpos(..)
181
182
183        template<class Ch, class Tr, class Alloc>
184        typename basic_altstringbuf<Ch, Tr, Alloc>::int_type
185        basic_altstringbuf<Ch, Tr, Alloc>:: 
186        underflow () {
187            if(gptr() == NULL) // no get area -> nothing to get.
188                return (compat_traits_type::eof()); 
189            else if(gptr() < egptr())  // ok, in buffer
190                return (compat_traits_type::to_int_type(*gptr())); 
191            else if(mode_ & ::std::ios_base::in && pptr() != NULL
192                    && (gptr() < pptr() || gptr() < putend_) )
193                {  // expand get area 
194                    if(putend_ < pptr()) 
195                        putend_ = pptr(); // remember pptr reached this far
196                    streambuf_t::setg(eback(), gptr(), putend_);
197                    return (compat_traits_type::to_int_type(*gptr()));
198                }
199            else // couldnt get anything. EOF.
200                return (compat_traits_type::eof());
201        }
202        // -end underflow(..)
203
204
205        template<class Ch, class Tr, class Alloc>
206        typename basic_altstringbuf<Ch, Tr, Alloc>::int_type 
207        basic_altstringbuf<Ch, Tr, Alloc>:: 
208        pbackfail (int_type meta) {
209            if(gptr() != NULL  &&  (eback() < gptr()) 
210               && (mode_ & (::std::ios_base::out)
211                   || compat_traits_type::eq_int_type(compat_traits_type::eof(), meta)
212                   || compat_traits_type::eq(compat_traits_type::to_char_type(meta), gptr()[-1]) ) ) { 
213                streambuf_t::gbump(-1); // back one character
214                if(!compat_traits_type::eq_int_type(compat_traits_type::eof(), meta))
215                    //  put-back meta into get area
216                    *gptr() = compat_traits_type::to_char_type(meta);
217                return (compat_traits_type::not_eof(meta));
218            }
219            else
220                return (compat_traits_type::eof());  // failed putback
221        }
222        // -end pbackfail(..)
223
224
225        template<class Ch, class Tr, class Alloc>
226        typename basic_altstringbuf<Ch, Tr, Alloc>::int_type 
227        basic_altstringbuf<Ch, Tr, Alloc>:: 
228        overflow (int_type meta) {
229#ifdef BOOST_MSVC
230#pragma warning(push)
231#pragma warning(disable:4996)
232#endif
233            if(compat_traits_type::eq_int_type(compat_traits_type::eof(), meta))
234                return compat_traits_type::not_eof(meta); // nothing to do
235            else if(pptr() != NULL && pptr() < epptr()) {
236                streambuf_t::sputc(compat_traits_type::to_char_type(meta));
237                return meta;
238            }
239            else if(! (mode_ & ::std::ios_base::out)) 
240                // no write position, and cant make one
241                return compat_traits_type::eof(); 
242            else { // make a write position available
243                std::size_t prev_size = pptr() == NULL ? 0 : epptr() - eback();
244                std::size_t new_size = prev_size;
245                // exponential growth : size *= 1.5
246                std::size_t add_size = new_size / 2;
247                if(add_size < alloc_min)
248                    add_size = alloc_min;
249                Ch * newptr = NULL,  *oldptr = eback();
250
251                // make sure adding add_size wont overflow size_t
252                while (0 < add_size && ((std::numeric_limits<std::size_t>::max)()
253                                        - add_size < new_size) )
254                    add_size /= 2;
255                if(0 < add_size) {
256                    new_size += add_size;
257#ifdef _RWSTD_NO_CLASS_PARTIAL_SPEC
258                    void *vdptr = alloc_.allocate(new_size, is_allocated_? oldptr : 0);
259                    newptr = static_cast<Ch *>(vdptr);
260#else
261                    newptr = alloc_.allocate(new_size, is_allocated_? oldptr : 0);
262#endif
263                }
264
265                if(0 < prev_size)
266                    compat_traits_type::copy(newptr, oldptr, prev_size);
267                if(is_allocated_)
268                    alloc_.deallocate(oldptr, prev_size);
269                is_allocated_=true;
270
271                if(prev_size == 0) { // first allocation
272                    putend_ = newptr;
273                    streambuf_t::setp(newptr, newptr + new_size);
274                    if(mode_ & ::std::ios_base::in)
275                        streambuf_t::setg(newptr, newptr, newptr + 1);
276                    else
277                        streambuf_t::setg(newptr, 0, newptr);
278                }
279                else { // update pointers
280                    putend_ = putend_ - oldptr + newptr;
281                    int pptr_count = static_cast<int>(pptr()-pbase());
282                    int gptr_count = static_cast<int>(gptr()-eback());
283                    streambuf_t::setp(pbase() - oldptr + newptr, newptr + new_size);
284                    streambuf_t::pbump(pptr_count);
285                    if(mode_ & ::std::ios_base::in)
286                        streambuf_t::setg(newptr, newptr + gptr_count, pptr() + 1);
287                    else
288                        streambuf_t::setg(newptr, 0, newptr);
289                }
290                streambuf_t::sputc(compat_traits_type::to_char_type(meta));
291                return meta;
292            }
293#ifdef BOOST_MSVC
294#pragma warning(pop)
295#endif
296        }
297        // -end overflow(..)
298
299        template<class Ch, class Tr, class Alloc>
300        void basic_altstringbuf<Ch, Tr, Alloc>:: dealloc() {
301            if(is_allocated_)
302                alloc_.deallocate(eback(), (pptr() != NULL ? epptr() : egptr()) - eback());
303            is_allocated_ = false;
304            streambuf_t::setg(0, 0, 0);
305            streambuf_t::setp(0, 0);
306            putend_ = NULL;
307        }
308
309    }// N.S. io
310} // N.S. boost
311
312#endif // include guard
313