Bitcoin Core
31.1.0
P2P Digital Currency
Toggle main menu visibility
Loading...
Searching...
No Matches
src
streams.cpp
Go to the documentation of this file.
1
// Copyright (c) 2009-present The Bitcoin Core developers
2
// Distributed under the MIT software license, see the accompanying
3
// file COPYING or https://opensource.org/license/mit/.
4
5
#include <
memusage.h
>
6
#include <
span.h
>
7
#include <
streams.h
>
8
#include <
util/fs_helpers.h
>
9
#include <
util/obfuscation.h
>
10
11
#include <array>
12
13
AutoFile::AutoFile
(std::FILE* file,
const
Obfuscation
& obfuscation) :
m_file
{file},
m_obfuscation
{obfuscation}
14
{
15
if
(!
IsNull
()) {
16
auto
pos{std::ftell(
m_file
)};
17
if
(pos >= 0)
m_position
= pos;
18
}
19
}
20
21
std::size_t
AutoFile::detail_fread
(std::span<std::byte> dst)
22
{
23
if
(!
m_file
)
throw
std::ios_base::failure(
"AutoFile::read: file handle is nullptr"
);
24
const
size_t
ret
= std::fread(dst.data(), 1, dst.size(),
m_file
);
25
if
(
m_obfuscation
) {
26
if
(!
m_position
)
throw
std::ios_base::failure(
"AutoFile::read: position unknown"
);
27
m_obfuscation
(dst.subspan(0,
ret
), *
m_position
);
28
}
29
if
(
m_position
) *
m_position
+=
ret
;
30
return
ret
;
31
}
32
33
void
AutoFile::seek
(int64_t offset,
int
origin)
34
{
35
if
(
IsNull
()) {
36
throw
std::ios_base::failure(
"AutoFile::seek: file handle is nullptr"
);
37
}
38
if
(std::fseek(
m_file
, offset, origin) != 0) {
39
throw
std::ios_base::failure(
feof
() ?
"AutoFile::seek: end of file"
:
"AutoFile::seek: fseek failed"
);
40
}
41
if
(origin == SEEK_SET) {
42
m_position
= offset;
43
}
else
if
(origin == SEEK_CUR &&
m_position
.has_value()) {
44
*
m_position
+= offset;
45
}
else
{
46
int64_t r{std::ftell(
m_file
)};
47
if
(r < 0) {
48
throw
std::ios_base::failure(
"AutoFile::seek: ftell failed"
);
49
}
50
m_position
= r;
51
}
52
}
53
54
int64_t
AutoFile::tell
()
55
{
56
if
(!
m_position
.has_value())
throw
std::ios_base::failure(
"AutoFile::tell: position unknown"
);
57
return
*
m_position
;
58
}
59
60
int64_t
AutoFile::size
()
61
{
62
if
(
IsNull
()) {
63
throw
std::ios_base::failure(
"AutoFile::size: file handle is nullptr"
);
64
}
65
// Temporarily save the current position
66
int64_t current_pos =
tell
();
67
seek
(0, SEEK_END);
68
int64_t file_size =
tell
();
69
// Restore the original position
70
seek
(current_pos, SEEK_SET);
71
return
file_size;
72
}
73
74
void
AutoFile::read
(std::span<std::byte> dst)
75
{
76
if
(
detail_fread
(dst) != dst.size()) {
77
throw
std::ios_base::failure(
feof
() ?
"AutoFile::read: end of file"
:
"AutoFile::read: fread failed"
);
78
}
79
}
80
81
void
AutoFile::ignore
(
size_t
nSize)
82
{
83
if
(!
m_file
)
throw
std::ios_base::failure(
"AutoFile::ignore: file handle is nullptr"
);
84
unsigned
char
data[4096];
85
while
(nSize > 0) {
86
size_t
nNow = std::min<size_t>(nSize,
sizeof
(data));
87
if
(std::fread(data, 1, nNow,
m_file
) != nNow) {
88
throw
std::ios_base::failure(
feof
() ?
"AutoFile::ignore: end of file"
:
"AutoFile::ignore: fread failed"
);
89
}
90
nSize -= nNow;
91
if
(
m_position
.has_value()) *
m_position
+= nNow;
92
}
93
}
94
95
void
AutoFile::write
(std::span<const std::byte> src)
96
{
97
if
(!
m_file
)
throw
std::ios_base::failure(
"AutoFile::write: file handle is nullptr"
);
98
if
(!
m_obfuscation
) {
99
if
(std::fwrite(src.data(), 1, src.size(),
m_file
) != src.size()) {
100
throw
std::ios_base::failure(
"AutoFile::write: write failed"
);
101
}
102
m_was_written
=
true
;
103
if
(
m_position
.has_value()) *
m_position
+= src.size();
104
}
else
{
105
std::array<std::byte, 4096> buf;
106
while
(src.size()) {
107
auto
buf_now{std::span{buf}.first(std::min<size_t>(src.size(), buf.size()))};
108
std::copy_n(src.begin(), buf_now.size(), buf_now.begin());
109
write_buffer
(buf_now);
110
src = src.subspan(buf_now.size());
111
}
112
}
113
}
114
115
void
AutoFile::write_buffer
(std::span<std::byte> src)
116
{
117
if
(!
m_file
)
throw
std::ios_base::failure(
"AutoFile::write_buffer: file handle is nullptr"
);
118
if
(
m_obfuscation
) {
119
if
(!
m_position
)
throw
std::ios_base::failure(
"AutoFile::write_buffer: obfuscation position unknown"
);
120
m_obfuscation
(src, *
m_position
);
// obfuscate in-place
121
}
122
if
(std::fwrite(src.data(), 1, src.size(),
m_file
) != src.size()) {
123
throw
std::ios_base::failure(
"AutoFile::write_buffer: write failed"
);
124
}
125
m_was_written
=
true
;
126
if
(
m_position
) *
m_position
+= src.size();
127
}
128
129
bool
AutoFile::Commit
()
130
{
131
return ::FileCommit(
m_file
);
132
}
133
134
bool
AutoFile::Truncate
(
unsigned
size
)
135
{
136
m_was_written
=
true
;
137
return ::TruncateFile(
m_file
,
size
);
138
}
139
140
size_t
DataStream::GetMemoryUsage
() const noexcept
141
{
142
return
sizeof
(*this) +
memusage::DynamicUsage
(
vch
);
143
}
ret
int ret
Definition
bitcoin-cli.cpp:1350
AutoFile::feof
bool feof() const
Definition
streams.h:405
AutoFile::ignore
void ignore(size_t nSize)
Definition
streams.cpp:81
AutoFile::write_buffer
void write_buffer(std::span< std::byte > src)
Write a mutable buffer more efficiently than write(), obfuscating the buffer in-place.
Definition
streams.cpp:115
AutoFile::m_file
std::FILE * m_file
Definition
streams.h:375
AutoFile::seek
void seek(int64_t offset, int origin)
Wrapper around fseek().
Definition
streams.cpp:33
AutoFile::size
int64_t size()
Return the size of the file.
Definition
streams.cpp:60
AutoFile::detail_fread
std::size_t detail_fread(std::span< std::byte > dst)
Implementation detail, only used internally.
Definition
streams.cpp:21
AutoFile::IsNull
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
Definition
streams.h:426
AutoFile::AutoFile
AutoFile(std::FILE *file, const Obfuscation &obfuscation={})
Definition
streams.cpp:13
AutoFile::Truncate
bool Truncate(unsigned size)
Wrapper around TruncateFile().
Definition
streams.cpp:134
AutoFile::m_was_written
bool m_was_written
Definition
streams.h:378
AutoFile::write
void write(std::span< const std::byte > src)
Definition
streams.cpp:95
AutoFile::m_position
std::optional< int64_t > m_position
Definition
streams.h:377
AutoFile::m_obfuscation
Obfuscation m_obfuscation
Definition
streams.h:376
AutoFile::tell
int64_t tell()
Find position within the file.
Definition
streams.cpp:54
AutoFile::Commit
bool Commit()
Wrapper around FileCommit().
Definition
streams.cpp:129
AutoFile::read
void read(std::span< std::byte > dst)
Definition
streams.cpp:74
DataStream::vch
vector_type vch
Definition
streams.h:136
DataStream::GetMemoryUsage
size_t GetMemoryUsage() const noexcept
Compute total memory usage of this object (own memory + any dynamic memory).
Definition
streams.cpp:140
Obfuscation
Definition
obfuscation.h:20
fs_helpers.h
memusage.h
memusage::DynamicUsage
static size_t DynamicUsage(const int8_t &v)
Dynamic memory usage for built-in types is zero.
Definition
memusage.h:31
obfuscation.h
span.h
streams.h
Generated on
for Bitcoin Core by
1.17.0