4 t_size remaining = p_bytes, written = 0;
7 if (delta > remaining) delta = remaining;
23 if (m_buffer_state > 0) {
37 t_size todo = p_bytes, done = 0;
42 m_reader->read_lendian_t(temp,p_abort);
44 if (temp !=
sizeof(
m_buffer)) m_eof =
true;
46 if (m_buffer_size>0) {
47 m_reader->read_object(
m_buffer,m_buffer_size,p_abort);
53 if (delta > todo) delta = todo;
55 memcpy((
unsigned char*)p_buffer + done,
m_buffer + m_buffer_state,delta);
58 m_buffer_state += delta;
68 m_reader->read_lendian_t(temp,p_abort);
70 if (temp !=
sizeof(
m_buffer)) m_eof =
true;
72 if (m_buffer_size>0) {
73 m_reader->skip_object(m_buffer_size,p_abort);
91 t_size max = get_buffer_size();
95 if (delta > max) delta = max;
96 memcpy(p_buffer,(
char*)get_buffer() + m_offset,delta);
104 if (position ==
filesize_invalid || position > max)
throw exception_io_seek_out_of_range();
105 m_offset = (
t_size)position;
112 const size_t readAmount = 64 * 1024;
114 f->seek(offset, aborter);
115 t_filesize positionGot = f->get_position(aborter);
116 if (positionGot != offset) {
117 FB2K_console_formatter() <<
"File sanity: at " << offset <<
" reported position became " << positionGot;
118 throw std::runtime_error(
"Seek test failure");
120 size_t did = f->read(buf.
get_ptr(), readAmount, aborter);
121 size_t expected = pfc::min_t<size_t>(readAmount, content.
get_size() - offset);
122 if (expected != did) {
123 FB2K_console_formatter() <<
"File sanity: at " << offset <<
" bytes, expected read size of " << expected <<
", got " << did;
124 if (did > expected) FB2K_console_formatter() <<
"Read past EOF";
125 else FB2K_console_formatter() <<
"Premature EOF";
126 throw std::runtime_error(
"Seek test failure");
128 if (memcmp(buf.
get_ptr(), content.
get_ptr() + offset, did) != 0) {
129 FB2K_console_formatter() <<
"File sanity: data mismatch at " << offset <<
" - " << (offset + did) <<
" bytes";
130 throw std::runtime_error(
"Seek test failure");
132 positionGot = f->get_position(aborter);
133 if (positionGot != offset + did) {
134 FB2K_console_formatter() <<
"File sanity: at " << offset <<
"+" << did <<
"=" << (offset + did) <<
" reported position became " << positionGot;
135 throw std::runtime_error(
"Seek test failure");
143 f->read_till_eof(fileContent, aborter);
146 t_filesize sizeClaimed = f->get_size(aborter);
148 FB2K_console_formatter() <<
"File sanity: file reports unknown size, actual size read is " << fileContent.
get_size();
151 if (sizeClaimed != fileContent.
get_size()) {
152 FB2K_console_formatter() <<
"File sanity: file reports size of " << sizeClaimed <<
", actual size read is " << fileContent.
get_size();
153 throw std::runtime_error(
"File size mismatch");
156 FB2K_console_formatter() <<
"File sanity: file size check OK: " << sizeClaimed;
162 FB2K_console_formatter() <<
"File sanity: testing N-first-bytes reads...";
163 const size_t sizeUpTo = pfc::min_t<size_t>(fileContent.
get_size(), 1024 * 1024);
167 for (
size_t w = 1; w <= sizeUpTo; w <<= 1) {
169 size_t did = f->read(buf1.get_ptr(), w, aborter);
171 FB2K_console_formatter() <<
"File sanity: premature EOF reading first " << w <<
" bytes, got " << did;
172 throw std::runtime_error(
"Premature EOF");
174 if (memcmp(fileContent.
get_ptr(), buf1.get_ptr(), did) != 0) {
175 FB2K_console_formatter() <<
"File sanity: file content mismatch reading first " << w <<
" bytes";
176 throw std::runtime_error(
"File content mismatch");
181 FB2K_console_formatter() <<
"File sanity: testing random access...";
184 size_t sizeUpTo = pfc::min_t<size_t>(fileContent.
get_size(), 1024 * 1024);
185 for (
size_t w = 1; w < sizeUpTo; w <<= 1) {
189 for (
size_t w = 1; w < sizeUpTo; w <<= 1) {
195 FB2K_console_formatter() <<
"File sanity test: all OK";
199 FB2K_console_formatter() <<
"File sanity test failure: " << e.what();
207 class listDirectoryCallback :
public directory_callback {
209 bool on_entry(filesystem * p_owner,
abort_callback & p_abort,
const char * p_url,
bool p_is_subdirectory,
const t_filestats & p_stats) {
210 m_func( p_url, p_stats, p_is_subdirectory );
219 listDirectoryCallback cb; cb.m_func = func;
220 filesystem::g_list_directory(path, cb, aborter);
const t_item * get_ptr() const
const t_item * get_ptr() const
This class is used to signal underlying worker code whether user has decided to abort a potentially t...
Special simplififed version of array class that avoids stepping on landmines with classes without pub...
void flush(abort_callback &p_abort)
void listDirectory(const char *path, abort_callback &aborter, listDirectoryFunc_t func)
static const t_filesize filesize_invalid
Invalid/unknown file size constant. Also see: t_filesize.
void seek(t_filesize position, abort_callback &p_abort)
unsigned char m_buffer[255]
void write(const void *p_buffer, t_size p_bytes, abort_callback &p_abort)
Contains various I/O related structures and interfaces.
t_size read(void *p_buffer, t_size p_bytes, abort_callback &p_abort)
bool fb2kFileSelfTest(file::ptr f, abort_callback &aborter)
Debug self-test function for testing a file object implementation, performs various behavior validity...
void flush(abort_callback &p_abort)
static void g_skip(stream_reader *p_stream, abort_callback &p_abort)
t_size read(void *p_buffer, t_size p_bytes, abort_callback &p_abort)
std::function< void(const char *, t_filestats const &, bool) > listDirectoryFunc_t
t_uint64 t_filesize
Type used for file size related variables.
static void fileSanitySeek(file::ptr f, pfc::array_t< uint8_t > const &content, size_t offset, abort_callback &aborter)
void set_size_discard(t_size p_size)
PFC_NORETURN void SHARED_EXPORT uBugCheck()