15afb937dSMark de Wever //===----------------------------------------------------------------------===// 25afb937dSMark de Wever // 35afb937dSMark de Wever // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45afb937dSMark de Wever // See https://llvm.org/LICENSE.txt for license information. 55afb937dSMark de Wever // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65afb937dSMark de Wever // 75afb937dSMark de Wever //===----------------------------------------------------------------------===// 85afb937dSMark de Wever 95afb937dSMark de Wever // <fstream> 105afb937dSMark de Wever 115afb937dSMark de Wever // basic_streambuf<charT, traits>* setbuf(char_type* s, streamsize n) override; 125afb937dSMark de Wever 13*0547e573SLouis Dionne // In C++23 and later, this test requires support for P2467R1 in the dylib (a3f17ba3febbd546f2342ffc780ac93b694fdc8d) 14*0547e573SLouis Dionne // XFAIL: (!c++03 && !c++11 && !c++14 && !c++17 && !c++20) && using-built-library-before-llvm-18 15*0547e573SLouis Dionne 165afb937dSMark de Wever #include <fstream> 175afb937dSMark de Wever #include <cstddef> 185afb937dSMark de Wever #include <cassert> 195afb937dSMark de Wever 205afb937dSMark de Wever #include "test_macros.h" 215afb937dSMark de Wever 225afb937dSMark de Wever template <class CharT> 235afb937dSMark de Wever static std::size_t file_size(const char* filename) { 245afb937dSMark de Wever FILE* f = std::fopen(filename, "rb"); 255afb937dSMark de Wever std::fseek(f, 0, SEEK_END); 265afb937dSMark de Wever long result = std::ftell(f); 275afb937dSMark de Wever std::fclose(f); 285afb937dSMark de Wever return result; 295afb937dSMark de Wever } 305afb937dSMark de Wever 315afb937dSMark de Wever // Helper class to expose some protected std::basic_filebuf<CharT> members. 325afb937dSMark de Wever template <class CharT> 335afb937dSMark de Wever struct filebuf : public std::basic_filebuf<CharT> { 345afb937dSMark de Wever CharT* base() { return this->pbase(); } 355afb937dSMark de Wever CharT* ptr() { return this->pptr(); } 365afb937dSMark de Wever }; 375afb937dSMark de Wever 385afb937dSMark de Wever template <class CharT> 395afb937dSMark de Wever static void buffered_request() { 405afb937dSMark de Wever filebuf<CharT> buffer; 415afb937dSMark de Wever 425afb937dSMark de Wever CharT b[10] = {0}; 435afb937dSMark de Wever assert(buffer.pubsetbuf(b, 10) == &buffer); 445afb937dSMark de Wever 455afb937dSMark de Wever buffer.open("test.dat", std::ios_base::out); 465afb937dSMark de Wever buffer.sputc(CharT('a')); 475afb937dSMark de Wever assert(b[0] == 'a'); 485afb937dSMark de Wever 495afb937dSMark de Wever buffer.close(); 505afb937dSMark de Wever assert(file_size<CharT>("test.dat") == 1); 515afb937dSMark de Wever } 525afb937dSMark de Wever 535afb937dSMark de Wever template <class CharT> 545afb937dSMark de Wever static void unbuffered_request_before_open() { 555afb937dSMark de Wever filebuf<CharT> buffer; 565afb937dSMark de Wever 575afb937dSMark de Wever assert(buffer.pubsetbuf(nullptr, 0) == &buffer); 585afb937dSMark de Wever assert(buffer.base() == nullptr); 595afb937dSMark de Wever assert(buffer.ptr() == nullptr); 605afb937dSMark de Wever 615afb937dSMark de Wever buffer.open("test.dat", std::ios_base::out); 625afb937dSMark de Wever assert(buffer.base() == nullptr); 635afb937dSMark de Wever assert(buffer.ptr() == nullptr); 645afb937dSMark de Wever 655afb937dSMark de Wever buffer.sputc(CharT('a')); 665afb937dSMark de Wever assert(buffer.base() == nullptr); 675afb937dSMark de Wever assert(buffer.ptr() == nullptr); 685afb937dSMark de Wever 695afb937dSMark de Wever assert(file_size<CharT>("test.dat") == 1); 705afb937dSMark de Wever } 715afb937dSMark de Wever 725afb937dSMark de Wever template <class CharT> 735afb937dSMark de Wever static void unbuffered_request_after_open() { 745afb937dSMark de Wever filebuf<CharT> buffer; 755afb937dSMark de Wever 765afb937dSMark de Wever buffer.open("test.dat", std::ios_base::out); 775afb937dSMark de Wever 785afb937dSMark de Wever assert(buffer.pubsetbuf(nullptr, 0) == &buffer); 795afb937dSMark de Wever assert(buffer.base() == nullptr); 805afb937dSMark de Wever assert(buffer.ptr() == nullptr); 815afb937dSMark de Wever 825afb937dSMark de Wever buffer.sputc(CharT('a')); 835afb937dSMark de Wever assert(buffer.base() == nullptr); 845afb937dSMark de Wever assert(buffer.ptr() == nullptr); 855afb937dSMark de Wever 865afb937dSMark de Wever assert(file_size<CharT>("test.dat") == 1); 875afb937dSMark de Wever } 885afb937dSMark de Wever 895afb937dSMark de Wever template <class CharT> 905afb937dSMark de Wever static void unbuffered_request_after_open_ate() { 915afb937dSMark de Wever filebuf<CharT> buffer; 925afb937dSMark de Wever 935afb937dSMark de Wever buffer.open("test.dat", std::ios_base::out | std::ios_base::ate); 945afb937dSMark de Wever 955afb937dSMark de Wever assert(buffer.pubsetbuf(nullptr, 0) == &buffer); 965afb937dSMark de Wever 975afb937dSMark de Wever buffer.sputc(CharT('a')); 985afb937dSMark de Wever assert(file_size<CharT>("test.dat") <= 1); 995afb937dSMark de Wever // on libc++ buffering is used by default. 1005afb937dSMark de Wever LIBCPP_ASSERT(file_size<CharT>("test.dat") == 0); 1015afb937dSMark de Wever 1025afb937dSMark de Wever buffer.close(); 1035afb937dSMark de Wever assert(file_size<CharT>("test.dat") == 1); 1045afb937dSMark de Wever } 1055afb937dSMark de Wever 1065afb937dSMark de Wever template <class CharT> 1075afb937dSMark de Wever static void test() { 1085afb937dSMark de Wever buffered_request<CharT>(); 1095afb937dSMark de Wever 1105afb937dSMark de Wever unbuffered_request_before_open<CharT>(); 1115afb937dSMark de Wever unbuffered_request_after_open<CharT>(); 1125afb937dSMark de Wever unbuffered_request_after_open_ate<CharT>(); 1135afb937dSMark de Wever } 1145afb937dSMark de Wever 1155afb937dSMark de Wever int main(int, char**) { 1165afb937dSMark de Wever test<char>(); 1175afb937dSMark de Wever 1185afb937dSMark de Wever #ifndef TEST_HAS_NO_WIDE_CHARACTERS 1195afb937dSMark de Wever test<wchar_t>(); 1205afb937dSMark de Wever #endif 1215afb937dSMark de Wever 1225afb937dSMark de Wever return 0; 1235afb937dSMark de Wever } 124