2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libstdc++-v3 / testsuite / 27_io / basic_filebuf / underflow / wchar_t / 9178.cc
blob3059724b44e67772c74877505717ab7a07a4771b
1 // Copyright (C) 2003 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 2, or (at your option)
7 // any later version.
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING. If not, write to the Free
16 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 // USA.
19 // 27.8.1.4 Overridden virtual functions
21 #include <fstream>
22 #include <string>
23 #include <iterator>
24 #include <algorithm>
25 #include <locale>
26 #include <testsuite_hooks.h>
28 template <typename InternT, typename StateT = mbstate_t>
29 class checksumcvt : public std::codecvt<InternT, char, StateT>
31 typedef std::codecvt<InternT, char, StateT> Base;
32 static const size_t width = sizeof(InternT) + 1;
34 public:
35 typedef InternT intern_type;
36 typedef char extern_type;
38 explicit checksumcvt(size_t refs = 0)
39 : Base(refs)
40 { }
42 protected:
43 virtual typename std::codecvt<InternT, char, StateT>::result
44 do_out(StateT&, const intern_type* from,
45 const intern_type* from_end, const intern_type*& from_next,
46 extern_type* to, extern_type* to_end,
47 extern_type*& to_next) const
49 size_t len = std::min(static_cast<size_t>(from_end - from),
50 static_cast<size_t>(to_end - to) / width);
52 while (len--)
54 const char* p = reinterpret_cast<const char*>(from);
55 unsigned char checksum = 0;
57 for (size_t i = 0; i < sizeof(intern_type); ++i)
59 *to++ = p[i];
60 checksum ^= static_cast<unsigned char>(p[i]);
63 *to++ = checksum;
64 ++from;
67 from_next = from;
68 to_next = to;
69 return from_next == from_end ? std::codecvt<InternT, char, StateT>::ok
70 : std::codecvt<InternT, char, StateT>::partial;
73 virtual typename std::codecvt<InternT, char, StateT>::result
74 do_unshift(StateT&, extern_type* to,
75 extern_type*, extern_type*& to_next) const
77 to_next = to;
78 return std::codecvt<InternT, char, StateT>::ok;
81 virtual typename std::codecvt<InternT, char, StateT>::result
82 do_in(StateT&, const extern_type* from,
83 const extern_type* from_end, const extern_type*& from_next,
84 intern_type* to, intern_type* to_end,
85 intern_type*& to_next) const
87 size_t len = std::min(static_cast<size_t>(to_end - to),
88 static_cast<size_t>(from_end - from) / width);
90 while (len)
92 const char* f = from;
93 intern_type tmp;
94 char* p = reinterpret_cast<char*>(&tmp);
95 unsigned char checksum = 0;
97 for (size_t i = 0; i < sizeof(intern_type); ++i)
99 p[i] = *f;
100 checksum ^= static_cast<unsigned char>(*f++);
103 if (*f++ != checksum)
104 break;
106 from = f;
107 *to++ = tmp;
108 len--;
111 from_next = from;
112 to_next = to;
113 return len ? std::codecvt<InternT, char, StateT>::error :
114 (from_next == from_end ? std::codecvt<InternT, char, StateT>::ok
115 : std::codecvt<InternT, char, StateT>::partial);
118 virtual int
119 do_encoding() const throw()
121 return width;
124 virtual int
125 do_length(StateT&, const extern_type* from,
126 const extern_type* end, size_t max) const
128 size_t len = std::min(max, static_cast<size_t>(end - from) / width);
130 int ret = 0;
131 while (len--)
133 unsigned char checksum = 0;
135 for (size_t i = 0; i < sizeof(intern_type); ++i)
137 checksum ^= static_cast<unsigned char>(*from++);
140 if (*from++ != checksum)
141 break;
143 ret++;
146 return ret;
149 virtual int
150 do_max_length() const throw()
152 return width;
155 virtual bool
156 do_always_noconv() const throw()
158 return false;
162 void test01()
164 using namespace std;
165 bool test __attribute__((unused)) = true;
167 locale loc;
168 loc = locale(loc, new checksumcvt<wchar_t>);
170 wfilebuf fbuf1;
171 fbuf1.pubimbue(loc);
172 fbuf1.open("tmp_9178", ios_base::out | ios_base::trunc);
174 string tmpstr = "abcdefghijklmnopqrstuvwxyz0123456789 \t\n";
176 wifstream stream;
177 wstring str1;
179 while (str1.length() < 20000)
181 transform(tmpstr.begin(), tmpstr.end(),
182 back_inserter(str1),
183 bind1st(std::mem_fun(&std::wios::widen), &stream));
186 fbuf1.sputn(str1.data(), str1.size());
187 fbuf1.close();
189 wfilebuf fbuf2;
190 fbuf2.pubimbue(loc);
191 fbuf2.open("tmp_9178", std::ios_base::in);
193 wstring str2;
194 copy(istreambuf_iterator<wchar_t>(&fbuf2),
195 istreambuf_iterator<wchar_t>(),
196 back_inserter(str2));
198 VERIFY( str1 == str2 );
201 int main()
203 test01();
204 return 0;