1// Copyright (C) 2003, 2009 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 3, or (at your option) 7// any later version. 8 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. 13 14// You should have received a copy of the GNU General Public License along 15// with this library; see the file COPYING3. If not see 16// <http://www.gnu.org/licenses/>. 17 18// 27.8.1.4 Overridden virtual functions 19 20#include <fstream> 21#include <locale> 22#include <algorithm> 23#include <cstring> 24#include <testsuite_hooks.h> 25 26class Cvt : public std::codecvt<wchar_t, char, mbstate_t> 27{ 28protected: 29 virtual std::codecvt_base::result 30 do_out(std::mbstate_t&, const wchar_t* from, const wchar_t* from_end, 31 const wchar_t*& from_next, char* to, char* to_end, 32 char*& to_next) const 33 { 34 std::size_t from_len = from_end - from; 35 std::size_t to_len = (to_end - to) / sizeof(wchar_t); 36 std::size_t len = std::min(from_len, to_len); 37 std::memcpy(to, from, len * sizeof(wchar_t)); 38 from_next = from + len; 39 to_next = to + len * sizeof(wchar_t); 40 return from_next == from_end ? std::codecvt_base::ok : 41 std::codecvt_base::partial; 42 } 43 44 virtual std::codecvt_base::result 45 do_in(std::mbstate_t&, const char* from, const char* from_end, 46 const char*& from_next, wchar_t* to, wchar_t* to_end, 47 wchar_t*& to_next) const 48 { 49 std::size_t from_len = 50 (from_end - from) / sizeof(wchar_t); 51 std::size_t to_len = to_end - to; 52 std::size_t len = std::min(from_len, to_len); 53 std::memcpy(to, from, len * sizeof(wchar_t)); 54 from_next = from + len * sizeof(wchar_t); 55 to_next = to + len; 56 return from_next == from_end ? std::codecvt_base::ok : 57 std::codecvt_base::partial; 58 } 59 60 virtual std::codecvt_base::result 61 do_unshift(std::mbstate_t&, char*, char*, char*&) const 62 { return std::codecvt_base::noconv; } 63 64 virtual int do_encoding() const throw() { return sizeof(wchar_t); } 65 virtual bool do_always_noconv() const throw() { return false; } 66 67 virtual int 68 do_length(std::mbstate_t&, const char* from, const char* end, 69 std::size_t max) 70 { 71 std::size_t len = (end - from) / sizeof(wchar_t); 72 return std::min(len, max) * sizeof(wchar_t); 73 } 74 75 virtual int do_max_length() const throw() { return sizeof(wchar_t); } 76}; 77 78void test01() 79{ 80 using namespace std; 81 bool test __attribute__((unused)) = true; 82 83 // seekpos 84 wfilebuf fb; 85 fb.pubimbue(locale(locale::classic(), new Cvt)); 86 fb.open("tmp_9875_seekpos", ios_base::out | ios_base::in | ios_base::trunc); 87 fb.sputn(L"0123456789", 10); 88 89 streampos p1 = fb.pubseekoff(0, ios_base::cur); 90 VERIFY( p1 != streampos(-1) ); 91 fb.sputc(L'a'); 92 93 streampos p2 = fb.pubseekpos(p1); 94 VERIFY( p2 != streampos(-1) ); 95 VERIFY( p2 == p1 ); 96 VERIFY( fb.sgetc() == L'a' ); 97 98 fb.pubseekoff(0, ios_base::beg); 99 wchar_t buf[11]; 100 streamsize s1 = fb.sgetn(buf, 11); 101 VERIFY( s1 == 11 ); 102 VERIFY( !wmemcmp(buf, L"0123456789a", 11) ); 103 104 fb.close(); 105} 106 107int main() 108{ 109 test01(); 110 return 0; 111} 112