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. 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 COPYING. If not, write to the Free 16// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 17// USA. 18 19// 27.8.1.4 Overridden virtual functions 20 21#include <fstream> 22#include <locale> 23#include <algorithm> 24#include <cstring> 25#include <testsuite_hooks.h> 26 27class Cvt : public std::codecvt<wchar_t, char, mbstate_t> 28{ 29protected: 30 virtual std::codecvt_base::result 31 do_out(std::mbstate_t&, const wchar_t* from, const wchar_t* from_end, 32 const wchar_t*& from_next, char* to, char* to_end, 33 char*& to_next) const 34 { 35 std::size_t from_len = from_end - from; 36 std::size_t to_len = (to_end - to) / sizeof(wchar_t); 37 std::size_t len = std::min(from_len, to_len); 38 std::memcpy(to, from, len * sizeof(wchar_t)); 39 from_next = from + len; 40 to_next = to + len * sizeof(wchar_t); 41 return from_next == from_end ? std::codecvt_base::ok : 42 std::codecvt_base::partial; 43 } 44 45 virtual std::codecvt_base::result 46 do_in(std::mbstate_t&, const char* from, const char* from_end, 47 const char*& from_next, wchar_t* to, wchar_t* to_end, 48 wchar_t*& to_next) const 49 { 50 std::size_t from_len = 51 (from_end - from) / sizeof(wchar_t); 52 std::size_t to_len = to_end - to; 53 std::size_t len = std::min(from_len, to_len); 54 std::memcpy(to, from, len * sizeof(wchar_t)); 55 from_next = from + len * sizeof(wchar_t); 56 to_next = to + len; 57 return from_next == from_end ? std::codecvt_base::ok : 58 std::codecvt_base::partial; 59 } 60 61 virtual std::codecvt_base::result 62 do_unshift(std::mbstate_t&, char*, char*, char*&) const 63 { return std::codecvt_base::noconv; } 64 65 virtual int do_encoding() const throw() { return sizeof(wchar_t); } 66 virtual bool do_always_noconv() const throw() { return false; } 67 68 virtual int 69 do_length(std::mbstate_t&, const char* from, const char* end, 70 std::size_t max) 71 { 72 std::size_t len = (end - from) / sizeof(wchar_t); 73 return std::min(len, max) * sizeof(wchar_t); 74 } 75 76 virtual int do_max_length() const throw() { return sizeof(wchar_t); } 77}; 78 79void test01() 80{ 81 using namespace std; 82 bool test __attribute__((unused)) = true; 83 84 // seekoff 85 wfilebuf fb; 86 fb.pubimbue(locale(locale::classic(), new Cvt)); 87 fb.open("tmp_9875_seekoff", ios_base::out | ios_base::in | ios_base::trunc); 88 fb.sputn(L"0123456789", 10); 89 fb.pubseekoff(-3, ios_base::cur); 90 VERIFY( fb.sgetc() == L'7' ); 91 fb.pubseekoff(-3, ios_base::cur); 92 VERIFY( fb.sgetc() == L'4' ); 93 fb.close(); 94} 95 96int main() 97{ 98 test01(); 99 return 0; 100} 101