Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
F
fmt
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
fmt
Commits
f69b6eaa
Commit
f69b6eaa
authored
Jun 28, 2020
by
Victor Zverovich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add a simple buffered stream with no sync
parent
ba363b3a
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
81 additions
and
2 deletions
+81
-2
include/fmt/os.h
include/fmt/os.h
+59
-1
test/gtest-extra.h
test/gtest-extra.h
+2
-1
test/os-test.cc
test/os-test.cc
+20
-0
No files found.
include/fmt/os.h
View file @
f69b6eaa
...
...
@@ -277,7 +277,8 @@ class file {
enum
{
RDONLY
=
FMT_POSIX
(
O_RDONLY
),
// Open for reading only.
WRONLY
=
FMT_POSIX
(
O_WRONLY
),
// Open for writing only.
RDWR
=
FMT_POSIX
(
O_RDWR
)
// Open for reading and writing.
RDWR
=
FMT_POSIX
(
O_RDWR
),
// Open for reading and writing.
CREATE
=
FMT_POSIX
(
O_CREAT
)
// Create if the file doesn't exist.
};
// Constructs a file object which doesn't represent any file.
...
...
@@ -341,6 +342,63 @@ class file {
// Returns the memory page size.
long
getpagesize
();
class
direct_buffered_file
;
template
<
typename
S
,
typename
...
Args
>
void
print
(
direct_buffered_file
&
f
,
const
S
&
format_str
,
const
Args
&
...
args
);
// A buffered file with a direct buffer access and no synchronization.
class
direct_buffered_file
{
private:
file
file_
;
enum
{
buffer_size
=
4096
};
char
buffer_
[
buffer_size
];
int
pos_
;
void
flush
()
{
if
(
pos_
==
0
)
return
;
file_
.
write
(
buffer_
,
pos_
);
pos_
=
0
;
}
int
free_capacity
()
const
{
return
buffer_size
-
pos_
;
}
public:
direct_buffered_file
(
cstring_view
path
,
int
oflag
)
:
file_
(
path
,
oflag
),
pos_
(
0
)
{}
~
direct_buffered_file
()
{
flush
();
}
void
close
()
{
flush
();
file_
.
close
();
}
template
<
typename
S
,
typename
...
Args
>
friend
void
print
(
direct_buffered_file
&
f
,
const
S
&
format_str
,
const
Args
&
...
args
)
{
// We could avoid double buffering.
auto
buf
=
fmt
::
memory_buffer
();
fmt
::
format_to
(
std
::
back_inserter
(
buf
),
format_str
,
args
...);
auto
remaining_pos
=
0
;
auto
remaining_size
=
buf
.
size
();
while
(
remaining_size
>
detail
::
to_unsigned
(
f
.
free_capacity
()))
{
auto
size
=
f
.
free_capacity
();
memcpy
(
f
.
buffer_
+
f
.
pos_
,
buf
.
data
()
+
remaining_pos
,
size
);
f
.
pos_
+=
size
;
f
.
flush
();
remaining_pos
+=
size
;
remaining_size
-=
size
;
}
memcpy
(
f
.
buffer_
+
f
.
pos_
,
buf
.
data
()
+
remaining_pos
,
remaining_size
);
f
.
pos_
+=
static_cast
<
int
>
(
remaining_size
);
}
};
#endif // FMT_USE_FCNTL
#ifdef FMT_LOCALE
...
...
test/gtest-extra.h
View file @
f69b6eaa
...
...
@@ -141,7 +141,8 @@ class SuppressAssert {
std
::
string
read
(
fmt
::
file
&
f
,
size_t
count
);
# define EXPECT_READ(file, expected_content) \
EXPECT_EQ(expected_content, read(file, std::strlen(expected_content)))
EXPECT_EQ(expected_content, \
read(file, fmt::string_view(expected_content).size()))
#else
# define EXPECT_WRITE(file, statement, expected_output) SUCCEED()
...
...
test/os-test.cc
View file @
f69b6eaa
...
...
@@ -287,6 +287,26 @@ TEST(BufferedFileTest, Fileno) {
EXPECT_READ
(
copy
,
FILE_CONTENT
);
}
TEST
(
DirectBufferedFileTest
,
Print
)
{
fmt
::
direct_buffered_file
out
(
"test-file"
,
fmt
::
file
::
WRONLY
|
fmt
::
file
::
CREATE
);
fmt
::
print
(
out
,
"The answer is {}.
\n
"
,
42
);
out
.
close
();
file
in
(
"test-file"
,
file
::
RDONLY
);
EXPECT_READ
(
in
,
"The answer is 42.
\n
"
);
}
TEST
(
DirectBufferedFileTest
,
BufferBoundary
)
{
auto
str
=
std
::
string
(
4096
,
'x'
);
fmt
::
direct_buffered_file
out
(
"test-file"
,
fmt
::
file
::
WRONLY
|
fmt
::
file
::
CREATE
);
fmt
::
print
(
out
,
"{}"
,
str
);
fmt
::
print
(
out
,
"{}"
,
str
);
out
.
close
();
file
in
(
"test-file"
,
file
::
RDONLY
);
EXPECT_READ
(
in
,
str
+
str
);
}
TEST
(
FileTest
,
DefaultCtor
)
{
file
f
;
EXPECT_EQ
(
-
1
,
f
.
descriptor
());
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment