forked from OSchip/llvm-project
parent
b0c76394a3
commit
6508e9936c
|
@ -3795,16 +3795,27 @@ public:
|
|||
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 @@ public:
|
|||
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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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");
|
||||
}
|
|
@ -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');
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
123456789
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
乑乒乓
|
Loading…
Reference in New Issue