125 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// <fstream>10 11// basic_streambuf<charT, traits>* setbuf(char_type* s, streamsize n) override;12 13// This test requires the fix to https://llvm.org/PR60509 in the dylib,14// which landed in 5afb937d8a30445642ccaf33866ee4cdd0713222.15// XFAIL: using-built-library-before-llvm-1916 17#include <fstream>18#include <cstddef>19#include <cassert>20 21#include "test_macros.h"22 23template <class CharT>24static std::size_t file_size(const char* filename) {25 FILE* f = std::fopen(filename, "rb");26 std::fseek(f, 0, SEEK_END);27 long result = std::ftell(f);28 std::fclose(f);29 return result;30}31 32// Helper class to expose some protected std::basic_filebuf<CharT> members.33template <class CharT>34struct filebuf : public std::basic_filebuf<CharT> {35 CharT* base() { return this->pbase(); }36 CharT* ptr() { return this->pptr(); }37};38 39template <class CharT>40static void buffered_request() {41 filebuf<CharT> buffer;42 43 CharT b[10] = {0};44 assert(buffer.pubsetbuf(b, 10) == &buffer);45 46 buffer.open("test.dat", std::ios_base::out);47 buffer.sputc(CharT('a'));48 assert(b[0] == 'a');49 50 buffer.close();51 assert(file_size<CharT>("test.dat") == 1);52}53 54template <class CharT>55static void unbuffered_request_before_open() {56 filebuf<CharT> buffer;57 58 assert(buffer.pubsetbuf(nullptr, 0) == &buffer);59 assert(buffer.base() == nullptr);60 assert(buffer.ptr() == nullptr);61 62 buffer.open("test.dat", std::ios_base::out);63 assert(buffer.base() == nullptr);64 assert(buffer.ptr() == nullptr);65 66 buffer.sputc(CharT('a'));67 assert(buffer.base() == nullptr);68 assert(buffer.ptr() == nullptr);69 70 assert(file_size<CharT>("test.dat") == 1);71}72 73template <class CharT>74static void unbuffered_request_after_open() {75 filebuf<CharT> buffer;76 77 buffer.open("test.dat", std::ios_base::out);78 79 assert(buffer.pubsetbuf(nullptr, 0) == &buffer);80 assert(buffer.base() == nullptr);81 assert(buffer.ptr() == nullptr);82 83 buffer.sputc(CharT('a'));84 assert(buffer.base() == nullptr);85 assert(buffer.ptr() == nullptr);86 87 assert(file_size<CharT>("test.dat") == 1);88}89 90template <class CharT>91static void unbuffered_request_after_open_ate() {92 filebuf<CharT> buffer;93 94 buffer.open("test.dat", std::ios_base::out | std::ios_base::ate);95 96 assert(buffer.pubsetbuf(nullptr, 0) == &buffer);97 98 buffer.sputc(CharT('a'));99 assert(file_size<CharT>("test.dat") <= 1);100 // on libc++ buffering is used by default.101 LIBCPP_ASSERT(file_size<CharT>("test.dat") == 0);102 103 buffer.close();104 assert(file_size<CharT>("test.dat") == 1);105}106 107template <class CharT>108static void test() {109 buffered_request<CharT>();110 111 unbuffered_request_before_open<CharT>();112 unbuffered_request_after_open<CharT>();113 unbuffered_request_after_open_ate<CharT>();114}115 116int main(int, char**) {117 test<char>();118 119#ifndef TEST_HAS_NO_WIDE_CHARACTERS120 test<wchar_t>();121#endif122 123 return 0;124}125