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 // seekoff 84 wfilebuf fb; 85 fb.pubimbue(locale(locale::classic(), new Cvt)); 86 fb.open("tmp_9875_seekoff", ios_base::out | ios_base::in | ios_base::trunc); 87 fb.sputn(L"0123456789", 10); 88 fb.pubseekoff(-3, ios_base::cur); 89 VERIFY( fb.sgetc() == L'7' ); 90 fb.pubseekoff(-3, ios_base::cur); 91 VERIFY( fb.sgetc() == L'4' ); 92 fb.close(); 93} 94 95int main() 96{ 97 test01(); 98 return 0; 99} 100