1 //===-- Unittests for ftell -----------------------------------------------===//
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-exception
7 //===----------------------------------------------------------------------===//
9 #include "hdr/stdio_macros.h"
10 #include "src/stdio/fclose.h"
11 #include "src/stdio/fopen.h"
12 #include "src/stdio/fread.h"
13 #include "src/stdio/fseek.h"
14 #include "src/stdio/fseeko.h"
15 #include "src/stdio/ftell.h"
16 #include "src/stdio/ftello.h"
17 #include "src/stdio/fwrite.h"
18 #include "src/stdio/setvbuf.h"
19 #include "test/UnitTest/Test.h"
21 class LlvmLibcFTellTest
: public LIBC_NAMESPACE::testing::Test
{
23 void test_with_bufmode(int bufmode
) {
24 constexpr char FILENAME
[] = "testdata/ftell.test";
25 // We will set a special buffer to the file so that we guarantee buffering.
26 constexpr size_t BUFFER_SIZE
= 1024;
27 char buffer
[BUFFER_SIZE
];
28 ::FILE *file
= LIBC_NAMESPACE::fopen(FILENAME
, "w+");
29 ASSERT_FALSE(file
== nullptr);
30 ASSERT_EQ(LIBC_NAMESPACE::setvbuf(file
, buffer
, bufmode
, BUFFER_SIZE
), 0);
32 // Include few '\n' chars to test when |bufmode| is _IOLBF.
33 constexpr char CONTENT
[] = "12\n345\n6789";
34 constexpr size_t WRITE_SIZE
= sizeof(CONTENT
) - 1;
35 ASSERT_EQ(WRITE_SIZE
, LIBC_NAMESPACE::fwrite(CONTENT
, 1, WRITE_SIZE
, file
));
36 // The above write should have buffered the written data and not have
37 // trasferred it to the underlying stream. But, ftell operation should
38 // still return the correct effective offset.
39 ASSERT_EQ(size_t(LIBC_NAMESPACE::ftell(file
)), WRITE_SIZE
);
42 ASSERT_EQ(0, LIBC_NAMESPACE::fseeko(file
, offseto
, SEEK_SET
));
43 ASSERT_EQ(LIBC_NAMESPACE::ftello(file
), offseto
);
44 ASSERT_EQ(0, LIBC_NAMESPACE::fseeko(file
, -offseto
, SEEK_END
));
45 ASSERT_EQ(size_t(LIBC_NAMESPACE::ftello(file
)),
46 size_t(WRITE_SIZE
- offseto
));
49 ASSERT_EQ(0, LIBC_NAMESPACE::fseek(file
, offset
, SEEK_SET
));
50 ASSERT_EQ(LIBC_NAMESPACE::ftell(file
), offset
);
51 ASSERT_EQ(0, LIBC_NAMESPACE::fseek(file
, -offset
, SEEK_END
));
52 ASSERT_EQ(size_t(LIBC_NAMESPACE::ftell(file
)), size_t(WRITE_SIZE
- offset
));
54 ASSERT_EQ(0, LIBC_NAMESPACE::fseek(file
, 0, SEEK_SET
));
55 constexpr size_t READ_SIZE
= WRITE_SIZE
/ 2;
57 // Reading a small amount will actually read out much more data and
58 // buffer it. But, ftell should return the correct effective offset.
59 ASSERT_EQ(READ_SIZE
, LIBC_NAMESPACE::fread(data
, 1, READ_SIZE
, file
));
60 ASSERT_EQ(size_t(LIBC_NAMESPACE::ftell(file
)), READ_SIZE
);
62 ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file
));
66 TEST_F(LlvmLibcFTellTest
, TellWithFBF
) { test_with_bufmode(_IOFBF
); }
68 TEST_F(LlvmLibcFTellTest
, TellWithNBF
) { test_with_bufmode(_IONBF
); }
70 TEST_F(LlvmLibcFTellTest
, TellWithLBF
) { test_with_bufmode(_IOLBF
); }