[cfe-commits] [libcxx] r105286 - in /libcxx/trunk: include/ test/localization/locales/locale.convenience/conversions/conversions.buffer/

Howard Hinnant hhinnant at apple.com
Tue Jun 1 13:09:19 PDT 2010


Author: hhinnant
Date: Tue Jun  1 15:09:18 2010
New Revision: 105286

URL: http://llvm.org/viewvc/llvm-project?rev=105286&view=rev
Log:
[conversions.buffer]

Added:
    libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp
    libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/overflow.pass.cpp
    libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/pbackfail.pass.cpp
    libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/rdbuf.pass.cpp
    libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/seekoff.pass.cpp
    libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/state.pass.cpp
    libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/test.pass.cpp
    libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/underflow.dat
    libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/underflow.pass.cpp
    libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/underflow_utf8.dat   (with props)
Modified:
    libcxx/trunk/include/locale

Modified: libcxx/trunk/include/locale
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/locale?rev=105286&r1=105285&r2=105286&view=diff
==============================================================================
--- libcxx/trunk/include/locale (original)
+++ libcxx/trunk/include/locale Tue Jun  1 15:09:18 2010
@@ -3795,16 +3795,27 @@
     typedef typename _Codecvt::state_type  state_type;
 
 private:
+    char*       __extbuf_;
+    const char* __extbufnext_;
+    const char* __extbufend_;
+    char __extbuf_min_[8];
+    size_t __ebs_;
+    char_type* __intbuf_;
+    size_t __ibs_;
     streambuf* __bufptr_;
-    _Codecvt* __cvtptr_;
-    state_type __cvtstate_;
+    _Codecvt* __cv_;
+    state_type __st_;
+    ios_base::openmode __cm_;
+    bool __owns_eb_;
+    bool __owns_ib_;
+    bool __always_noconv_;
 
+    wbuffer_convert(const wbuffer_convert&);
+    wbuffer_convert& operator=(const wbuffer_convert&);
 public:
     wbuffer_convert(streambuf* __bytebuf = 0, _Codecvt* __pcvt = new _Codecvt,
-                    state_type __state = state_type())
-        : __bufptr_(__bytebuf), __cvtptr_(__pcvt), __cvtstate_(__state) {}
-
-    ~wbuffer_convert() {delete __cvtptr_;}
+                    state_type __state = state_type());
+    ~wbuffer_convert();
 
     streambuf* rdbuf() const {return __bufptr_;}
     streambuf* rdbuf(streambuf* __bytebuf)
@@ -3814,16 +3825,417 @@
         return __r;
     }
 
-    state_type state() const {return __cvtstate_;}
+    state_type state() const {return __st_;}
 
 protected:
+    virtual int_type underflow();
+    virtual int_type pbackfail(int_type __c = traits_type::eof());
     virtual int_type overflow (int_type __c = traits_type::eof());
+    virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s,
+                                                            streamsize __n);
+    virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
+                             ios_base::openmode __wch = ios_base::in | ios_base::out);
+    virtual pos_type seekpos(pos_type __sp,
+                             ios_base::openmode __wch = ios_base::in | ios_base::out);
+    virtual int sync();
+
+private:
+    bool __read_mode();
+    void __write_mode();
+    wbuffer_convert* __close();
 };
 
 template <class _Codecvt, class _Elem, class _Tr>
+wbuffer_convert<_Codecvt, _Elem, _Tr>::
+    wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state)
+    : __extbuf_(0),
+      __extbufnext_(0),
+      __extbufend_(0),
+      __ebs_(0),
+      __intbuf_(0),
+      __ibs_(0),
+      __bufptr_(__bytebuf),
+      __cv_(__pcvt),
+      __st_(__state),
+      __cm_(0),
+      __owns_eb_(false),
+      __owns_ib_(false),
+      __always_noconv_(__cv_ ? __cv_->always_noconv() : false)
+{
+    setbuf(0, 4096);
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+wbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert()
+{
+    __close();
+    delete __cv_;
+    if (__owns_eb_)
+        delete [] __extbuf_;
+    if (__owns_ib_)
+        delete [] __intbuf_;
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
+wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow()
+{
+    if (__cv_ == 0 || __bufptr_ == 0)
+        return traits_type::eof();
+    bool __initial = __read_mode();
+    char_type __1buf;
+    if (this->gptr() == 0)
+        this->setg(&__1buf, &__1buf+1, &__1buf+1);
+    const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
+    int_type __c = traits_type::eof();
+    if (this->gptr() == this->egptr())
+    {
+        memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
+        if (__always_noconv_)
+        {
+            streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz);
+            __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb);
+            if (__nmemb != 0)
+            {
+                this->setg(this->eback(),
+                           this->eback() + __unget_sz,
+                           this->eback() + __unget_sz + __nmemb);
+                __c = *this->gptr();
+            }
+        }
+        else
+        {
+            memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
+            __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
+            __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
+            streamsize __nmemb = min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz),
+                                 static_cast<streamsize>(__extbufend_ - __extbufnext_));
+            codecvt_base::result __r;
+            state_type __svs = __st_;
+            streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb);
+            if (__nr != 0)
+            {
+                __extbufend_ = __extbufnext_ + __nr;
+                char_type*  __inext;
+                __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,
+                                       this->eback() + __unget_sz,
+                                       this->egptr(), __inext);
+                if (__r == codecvt_base::noconv)
+                {
+                    this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_);
+                    __c = *this->gptr();
+                }
+                else if (__inext != this->eback() + __unget_sz)
+                {
+                    this->setg(this->eback(), this->eback() + __unget_sz, __inext);
+                    __c = *this->gptr();
+                }
+            }
+        }
+    }
+    else
+        __c = *this->gptr();
+    if (this->eback() == &__1buf)
+        this->setg(0, 0, 0);
+    return __c;
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
+wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c)
+{
+    if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr())
+    {
+        if (traits_type::eq_int_type(__c, traits_type::eof()))
+        {
+            this->gbump(-1);
+            return traits_type::not_eof(__c);
+        }
+        if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
+        {
+            this->gbump(-1);
+            *this->gptr() = traits_type::to_char_type(__c);
+            return __c;
+        }
+    }
+    return traits_type::eof();
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
 wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c)
 {
+    if (__cv_ == 0 || __bufptr_ == 0)
+        return traits_type::eof();
+    __write_mode();
+    char_type __1buf;
+    char_type* __pb_save = this->pbase();
+    char_type* __epb_save = this->epptr();
+    if (!traits_type::eq_int_type(__c, traits_type::eof()))
+    {
+        if (this->pptr() == 0)
+            this->setp(&__1buf, &__1buf+1);
+        *this->pptr() = traits_type::to_char_type(__c);
+        this->pbump(1);
+    }
+    if (this->pptr() != this->pbase())
+    {
+        if (__always_noconv_)
+        {
+            streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase());
+            if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
+                return traits_type::eof();
+        }
+        else
+        {
+            char* __extbe = __extbuf_;
+            codecvt_base::result __r;
+            do
+            {
+                const char_type* __e;
+                __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,
+                                        __extbuf_, __extbuf_ + __ebs_, __extbe);
+                if (__e == this->pbase())
+                    return traits_type::eof();
+                if (__r == codecvt_base::noconv)
+                {
+                    streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
+                    if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
+                        return traits_type::eof();
+                }
+                else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
+                {
+                    streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_);
+                    if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
+                        return traits_type::eof();
+                    if (__r == codecvt_base::partial)
+                    {
+                        this->setp((char_type*)__e, this->pptr());
+                        this->pbump(this->epptr() - this->pbase());
+                    }
+                }
+                else
+                    return traits_type::eof();
+            } while (__r == codecvt_base::partial);
+        }
+        this->setp(__pb_save, __epb_save);
+    }
+    return traits_type::not_eof(__c);
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+basic_streambuf<_Elem, _Tr>*
+wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n)
+{
+    this->setg(0, 0, 0);
+    this->setp(0, 0);
+    if (__owns_eb_)
+        delete [] __extbuf_;
+    if (__owns_ib_)
+        delete [] __intbuf_;
+    __ebs_ = __n;
+    if (__ebs_ > sizeof(__extbuf_min_))
+    {
+        if (__always_noconv_ && __s)
+        {
+            __extbuf_ = (char*)__s;
+            __owns_eb_ = false;
+        }
+        else
+        {
+            __extbuf_ = new char[__ebs_];
+            __owns_eb_ = true;
+        }
+    }
+    else
+    {
+        __extbuf_ = __extbuf_min_;
+        __ebs_ = sizeof(__extbuf_min_);
+        __owns_eb_ = false;
+    }
+    if (!__always_noconv_)
+    {
+        __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
+        if (__s && __ibs_ >= sizeof(__extbuf_min_))
+        {
+            __intbuf_ = __s;
+            __owns_ib_ = false;
+        }
+        else
+        {
+            __intbuf_ = new char_type[__ibs_];
+            __owns_ib_ = true;
+        }
+    }
+    else
+    {
+        __ibs_ = 0;
+        __intbuf_ = 0;
+        __owns_ib_ = false;
+    }
+    return this;
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
+wbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way,
+                                        ios_base::openmode __om)
+{
+    int __width = __cv_->encoding();
+    if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync())
+        return pos_type(off_type(-1));
+    // __width > 0 || __off == 0
+    switch (__way)
+    {
+    case ios_base::beg:
+        break;
+    case ios_base::cur:
+        break;
+    case ios_base::end:
+        break;
+    default:
+        return pos_type(off_type(-1));
+    }
+    pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om);
+    __r.state(__st_);
+    return __r;
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
+wbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch)
+{
+    if (__cv_ == 0 || __bufptr_ == 0 || sync())
+        return pos_type(off_type(-1));
+    if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1)))
+        return pos_type(off_type(-1));
+    return __sp;
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+int
+wbuffer_convert<_Codecvt, _Elem, _Tr>::sync()
+{
+    if (__cv_ == 0 || __bufptr_ == 0)
+        return 0;
+    if (__cm_ & ios_base::out)
+    {
+        if (this->pptr() != this->pbase())
+            if (overflow() == traits_type::eof())
+                return -1;
+        codecvt_base::result __r;
+        do
+        {
+            char* __extbe;
+            __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
+            streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_);
+            if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
+                return -1;
+        } while (__r == codecvt_base::partial);
+        if (__r == codecvt_base::error)
+            return -1;
+        if (__bufptr_->pubsync())
+            return -1;
+    }
+    else if (__cm_ & ios_base::in)
+    {
+        off_type __c;
+        if (__always_noconv_)
+            __c = this->egptr() - this->gptr();
+        else
+        {
+            int __width = __cv_->encoding();
+            __c = __extbufend_ - __extbufnext_;
+            if (__width > 0)
+                __c += __width * (this->egptr() - this->gptr());
+            else
+            {
+                if (this->gptr() != this->egptr())
+                {
+                    reverse(this->gptr(), this->egptr());
+                    codecvt_base::result __r;
+                    const char_type* __e = this->gptr();
+                    char* __extbe;
+                    do
+                    {
+                        __r = __cv_->out(__st_, __e, this->egptr(), __e,
+                                         __extbuf_, __extbuf_ + __ebs_, __extbe);
+                        switch (__r)
+                        {
+                        case codecvt_base::noconv:
+                            __c += this->egptr() - this->gptr();
+                            break;
+                        case codecvt_base::ok:
+                        case codecvt_base::partial:
+                            __c += __extbe - __extbuf_;
+                            break;
+                        default:
+                            return -1;
+                        }
+                    } while (__r == codecvt_base::partial);
+                }
+            }
+        }
+        if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1)))
+            return -1;
+        this->setg(0, 0, 0);
+        __cm_ = 0;
+    }
+    return 0;
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+bool
+wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode()
+{
+    if (!(__cm_ & ios_base::in))
+    {
+        this->setp(0, 0);
+        if (__always_noconv_)
+            this->setg((char_type*)__extbuf_,
+                       (char_type*)__extbuf_ + __ebs_,
+                       (char_type*)__extbuf_ + __ebs_);
+        else
+            this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
+        __cm_ = ios_base::in;
+        return true;
+    }
+    return false;
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+void
+wbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode()
+{
+    if (!(__cm_ & ios_base::out))
+    {
+        this->setg(0, 0, 0);
+        if (__ebs_ > sizeof(__extbuf_min_))
+        {
+            if (__always_noconv_)
+                this->setp((char_type*)__extbuf_,
+                           (char_type*)__extbuf_ + (__ebs_ - 1));
+            else
+                this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
+        }
+        else
+            this->setp(0, 0);
+        __cm_ = ios_base::out;
+    }
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+wbuffer_convert<_Codecvt, _Elem, _Tr>*
+wbuffer_convert<_Codecvt, _Elem, _Tr>::__close()
+{
+    wbuffer_convert* __rt = 0;
+    if (__cv_ != 0 && __bufptr_ != 0)
+    {
+        __rt = this;
+        if ((__cm_ & ios_base::out) && sync())
+            __rt = 0;
+    }
+    return __rt;
 }
 
 _LIBCPP_END_NAMESPACE_STD

Added: libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp?rev=105286&view=auto
==============================================================================
--- libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp (added)
+++ libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp Tue Jun  1 15:09:18 2010
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <locale>
+
+// wbuffer_convert<Codecvt, Elem, Tr>
+
+// wbuffer_convert(streambuf *bytebuf = 0, Codecvt *pcvt = new Codecvt,
+//                 state_type state = state_type());
+
+#include <locale>
+#include <codecvt>
+#include <sstream>
+#include <cassert>
+#include <new>
+
+int new_called = 0;
+
+void* operator new(std::size_t s) throw(std::bad_alloc)
+{
+    ++new_called;
+    return std::malloc(s);
+}
+
+void  operator delete(void* p) throw()
+{
+    --new_called;
+    std::free(p);
+}
+
+int main()
+{
+    typedef std::wbuffer_convert<std::codecvt_utf8<wchar_t> > B;
+    {
+        B b;
+        assert(b.rdbuf() == nullptr);
+        assert(new_called != 0);
+    }
+    assert(new_called == 0);
+    {
+        std::stringstream s;
+        B b(s.rdbuf());
+        assert(b.rdbuf() == s.rdbuf());
+        assert(new_called != 0);
+    }
+    assert(new_called == 0);
+    {
+        std::stringstream s;
+        B b(s.rdbuf(), new std::codecvt_utf8<wchar_t>);
+        assert(b.rdbuf() == s.rdbuf());
+        assert(new_called != 0);
+    }
+    assert(new_called == 0);
+    {
+        std::stringstream s;
+        B b(s.rdbuf(), new std::codecvt_utf8<wchar_t>, std::mbstate_t());
+        assert(b.rdbuf() == s.rdbuf());
+        assert(new_called != 0);
+    }
+    assert(new_called == 0);
+}

Added: libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/overflow.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/overflow.pass.cpp?rev=105286&view=auto
==============================================================================
--- libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/overflow.pass.cpp (added)
+++ libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/overflow.pass.cpp Tue Jun  1 15:09:18 2010
@@ -0,0 +1,100 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <locale>
+
+// wbuffer_convert<Codecvt, Elem, Tr>
+
+// int_type overflow(int_type c = traits::eof());
+
+// This test is not entirely portable
+
+#include <locale>
+#include <codecvt>
+#include <fstream>
+#include <cassert>
+
+struct test_buf
+    : public std::wbuffer_convert<std::codecvt_utf8<wchar_t> >
+{
+    typedef std::wbuffer_convert<std::codecvt_utf8<wchar_t> > base;
+    typedef base::char_type   char_type;
+    typedef base::int_type    int_type;
+    typedef base::traits_type traits_type;
+
+    explicit test_buf(std::streambuf* sb) : base(sb) {}
+
+    char_type* pbase() const {return base::pbase();}
+    char_type* pptr()  const {return base::pptr();}
+    char_type* epptr() const {return base::epptr();}
+    void gbump(int n) {base::gbump(n);}
+
+    virtual int_type overflow(int_type c = traits_type::eof()) {return base::overflow(c);}
+};
+
+int main()
+{
+    {
+        std::ofstream bs("overflow.dat");
+        test_buf f(bs.rdbuf());
+        assert(f.pbase() == 0);
+        assert(f.pptr() == 0);
+        assert(f.epptr() == 0);
+        assert(f.overflow(L'a') == L'a');
+        assert(f.pbase() != 0);
+        assert(f.pptr() == f.pbase());
+        assert(f.epptr() - f.pbase() == 4095);
+    }
+    {
+        std::ifstream bs("overflow.dat");
+        test_buf f(bs.rdbuf());
+        assert(f.sgetc() == L'a');
+    }
+    std::remove("overflow.dat");
+    {
+        std::ofstream bs("overflow.dat");
+        test_buf f(bs.rdbuf());
+        f.pubsetbuf(0, 0);
+        assert(f.pbase() == 0);
+        assert(f.pptr() == 0);
+        assert(f.epptr() == 0);
+        assert(f.overflow('a') == 'a');
+        assert(f.pbase() == 0);
+        assert(f.pptr() == 0);
+        assert(f.epptr() == 0);
+    }
+    {
+        std::ifstream bs("overflow.dat");
+        test_buf f(bs.rdbuf());
+        assert(f.sgetc() == L'a');
+    }
+    std::remove("overflow.dat");
+    {
+        std::ofstream bs("overflow.dat");
+        test_buf f(bs.rdbuf());
+        assert(f.sputc(0x4E51) == 0x4E51);
+        assert(f.sputc(0x4E52) == 0x4E52);
+        assert(f.sputc(0x4E53) == 0x4E53);
+    }
+    {
+        std::ifstream f("overflow.dat");
+        assert(f.is_open());
+        assert(f.get() == 0xE4);
+        assert(f.get() == 0xB9);
+        assert(f.get() == 0x91);
+        assert(f.get() == 0xE4);
+        assert(f.get() == 0xB9);
+        assert(f.get() == 0x92);
+        assert(f.get() == 0xE4);
+        assert(f.get() == 0xB9);
+        assert(f.get() == 0x93);
+        assert(f.get() == -1);
+    }
+    std::remove("overflow.dat");
+}    

Added: libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/pbackfail.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/pbackfail.pass.cpp?rev=105286&view=auto
==============================================================================
--- libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/pbackfail.pass.cpp (added)
+++ libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/pbackfail.pass.cpp Tue Jun  1 15:09:18 2010
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <locale>
+
+// wbuffer_convert<Codecvt, Elem, Tr>
+
+// int_type pbackfail(int_type c = traits::eof());
+
+// This test is not entirely portable
+
+#include <locale>
+#include <codecvt>
+#include <fstream>
+#include <cassert>
+
+struct test_buf
+    : public std::wbuffer_convert<std::codecvt_utf8<wchar_t> >
+{
+    typedef std::wbuffer_convert<std::codecvt_utf8<wchar_t> > base;
+    typedef base::char_type   char_type;
+    typedef base::int_type    int_type;
+    typedef base::traits_type traits_type;
+
+    explicit test_buf(std::streambuf* sb) : base(sb) {}
+
+    char_type* eback() const {return base::eback();}
+    char_type* gptr()  const {return base::gptr();}
+    char_type* egptr() const {return base::egptr();}
+    void gbump(int n) {base::gbump(n);}
+
+    virtual int_type pbackfail(int_type c = traits_type::eof()) {return base::pbackfail(c);}
+};
+
+int main()
+{
+    {
+        std::ifstream bs("underflow.dat");
+        test_buf f(bs.rdbuf());
+        assert(f.sbumpc() == L'1');
+        assert(f.sgetc() == L'2');
+        assert(f.pbackfail(L'a') == -1);
+    }
+    {
+        std::fstream bs("underflow.dat");
+        test_buf f(bs.rdbuf());
+        assert(f.sbumpc() == L'1');
+        assert(f.sgetc() == L'2');
+        assert(f.pbackfail(L'a') == -1);
+        assert(f.sbumpc() == L'2');
+        assert(f.sgetc() == L'3');
+    }
+}    

Added: libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/rdbuf.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/rdbuf.pass.cpp?rev=105286&view=auto
==============================================================================
--- libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/rdbuf.pass.cpp (added)
+++ libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/rdbuf.pass.cpp Tue Jun  1 15:09:18 2010
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <locale>
+
+// wbuffer_convert<Codecvt, Elem, Tr>
+
+// streambuf *rdbuf(streambuf *bytebuf);
+
+#include <locale>
+#include <codecvt>
+#include <sstream>
+#include <cassert>
+
+int main()
+{
+    typedef std::wbuffer_convert<std::codecvt_utf8<wchar_t> > B;
+    {
+        std::stringstream s;
+        B b;
+        assert(b.rdbuf() == nullptr);
+        b.rdbuf(s.rdbuf());
+        assert(b.rdbuf() == s.rdbuf());
+    }
+}

Added: libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/seekoff.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/seekoff.pass.cpp?rev=105286&view=auto
==============================================================================
--- libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/seekoff.pass.cpp (added)
+++ libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/seekoff.pass.cpp Tue Jun  1 15:09:18 2010
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <locale>
+
+// wbuffer_convert<Codecvt, Elem, Tr>
+
+// pos_type seekoff(off_type off, ios_base::seekdir way, 
+//                  ios_base::openmode which = ios_base::in | ios_base::out);
+// pos_type seekpos(pos_type sp, 
+//                  ios_base::openmode which = ios_base::in | ios_base::out);
+
+// This test is not entirely portable
+
+#include <locale>
+#include <codecvt>
+#include <fstream>
+#include <cassert>
+
+class test_codecvt
+    : public std::codecvt<wchar_t, char, std::mbstate_t>
+{
+    typedef std::codecvt<wchar_t, char, std::mbstate_t> base;
+public:
+    explicit test_codecvt(std::size_t refs = 0) : base(refs) {}
+    ~test_codecvt() {}
+};
+
+int main()
+{
+    {
+        wchar_t buf[10];
+        typedef std::wbuffer_convert<test_codecvt> test_buf;
+        typedef test_buf::pos_type pos_type;
+        std::fstream bs("seekoff.dat", std::ios::trunc | std::ios::in
+                                                       | std::ios::out);
+        test_buf f(bs.rdbuf());
+        f.pubsetbuf(buf, sizeof(buf)/sizeof(buf[0]));
+        f.sputn(L"abcdefghijklmnopqrstuvwxyz", 26);
+        assert(buf[0] == L'v');
+        pos_type p = f.pubseekoff(-15, std::ios_base::cur);
+        assert(p == 11);
+        assert(f.sgetc() == L'l');
+        f.pubseekoff(0, std::ios_base::beg);
+        assert(f.sgetc() == L'a');
+        f.pubseekoff(-1, std::ios_base::end);
+        assert(f.sgetc() == L'z');
+        assert(f.pubseekpos(p) == p);
+        assert(f.sgetc() == L'l');
+    }
+    std::remove("seekoff.dat");
+}

Added: libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/state.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/state.pass.cpp?rev=105286&view=auto
==============================================================================
--- libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/state.pass.cpp (added)
+++ libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/state.pass.cpp Tue Jun  1 15:09:18 2010
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <locale>
+
+// wbuffer_convert<Codecvt, Elem, Tr>
+
+// state_type state() const;
+
+#include <locale>
+#include <codecvt>
+#include <sstream>
+#include <cassert>
+
+int main()
+{
+    typedef std::wbuffer_convert<std::codecvt_utf8<wchar_t> > B;
+    {
+        B b;
+        std::mbstate_t s = b.state();
+    }
+}

Added: libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/test.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/test.pass.cpp?rev=105286&view=auto
==============================================================================
--- libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/test.pass.cpp (added)
+++ libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/test.pass.cpp Tue Jun  1 15:09:18 2010
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <locale>
+
+// wbuffer_convert<Codecvt, Elem, Tr>
+
+#include <fstream>
+#include <locale>
+#include <codecvt>
+#include <cassert>
+
+int main()
+{
+    {
+        std::ofstream bytestream("myfile.txt");
+        std::wbuffer_convert<std::codecvt_utf8<wchar_t> > mybuf(bytestream.rdbuf());
+        std::wostream mystr(&mybuf);
+        mystr << L"Hello" << std::endl;
+    }
+    {
+        std::ifstream bytestream("myfile.txt");
+        std::wbuffer_convert<std::codecvt_utf8<wchar_t> > mybuf(bytestream.rdbuf());
+        std::wistream mystr(&mybuf);
+        std::wstring ws;
+        mystr >> ws;
+        assert(ws == L"Hello");
+    }
+    std::remove("myfile.txt");
+}

Added: libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/underflow.dat
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/underflow.dat?rev=105286&view=auto
==============================================================================
--- libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/underflow.dat (added)
+++ libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/underflow.dat Tue Jun  1 15:09:18 2010
@@ -0,0 +1 @@
+123456789
\ No newline at end of file

Added: libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/underflow.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/underflow.pass.cpp?rev=105286&view=auto
==============================================================================
--- libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/underflow.pass.cpp (added)
+++ libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/underflow.pass.cpp Tue Jun  1 15:09:18 2010
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <locale>
+
+// wbuffer_convert<Codecvt, Elem, Tr>
+
+// int_type underflow();
+
+// This test is not entirely portable
+
+#include <locale>
+#include <codecvt>
+#include <fstream>
+#include <cassert>
+
+struct test_buf
+    : public std::wbuffer_convert<std::codecvt_utf8<wchar_t> >
+{
+    typedef std::wbuffer_convert<std::codecvt_utf8<wchar_t> > base;
+    typedef base::char_type   char_type;
+    typedef base::int_type    int_type;
+    typedef base::traits_type traits_type;
+
+    explicit test_buf(std::streambuf* sb) : base(sb) {}
+
+    char_type* eback() const {return base::eback();}
+    char_type* gptr()  const {return base::gptr();}
+    char_type* egptr() const {return base::egptr();}
+    void gbump(int n) {base::gbump(n);}
+
+    virtual int_type underflow() {return base::underflow();}
+};
+
+int main()
+{
+    {
+        std::ifstream bs("underflow.dat");
+        test_buf f(bs.rdbuf());
+        assert(f.eback() == 0);
+        assert(f.gptr() == 0);
+        assert(f.egptr() == 0);
+        assert(f.underflow() == L'1');
+        assert(f.eback() != 0);
+        assert(f.eback() == f.gptr());
+        assert(*f.gptr() == L'1');
+        assert(f.egptr() - f.eback() == 9);
+    }
+    {
+        std::ifstream bs("underflow.dat");
+        test_buf f(bs.rdbuf());
+        assert(f.eback() == 0);
+        assert(f.gptr() == 0);
+        assert(f.egptr() == 0);
+        assert(f.underflow() == L'1');
+        assert(f.eback() != 0);
+        assert(f.eback() == f.gptr());
+        assert(*f.gptr() == L'1');
+        assert(f.egptr() - f.eback() == 9);
+        f.gbump(8);
+        assert(f.sgetc() == L'9');
+        assert(f.eback()[0] == L'1');
+        assert(f.eback()[1] == L'2');
+        assert(f.eback()[2] == L'3');
+        assert(f.eback()[3] == L'4');
+        assert(f.gptr() - f.eback() == 8);
+        assert(*f.gptr() == L'9');
+        assert(f.egptr() - f.gptr() == 1);
+    }
+    {
+        std::ifstream bs("underflow_utf8.dat");
+        test_buf f(bs.rdbuf());
+        assert(f.sbumpc() == 0x4E51);
+        assert(f.sbumpc() == 0x4E52);
+        assert(f.sbumpc() == 0x4E53);
+        assert(f.sbumpc() == -1);
+    }
+}    

Added: libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/underflow_utf8.dat
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/underflow_utf8.dat?rev=105286&view=auto
==============================================================================
Binary file - no diff available.

Propchange: libcxx/trunk/test/localization/locales/locale.convenience/conversions/conversions.buffer/underflow_utf8.dat
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream





More information about the cfe-commits mailing list