foobar2000 SDK  2015-01-14
Functions
filesystem_helper.cpp File Reference

Go to the source code of this file.

Functions

bool fb2kFileSelfTest (file::ptr f, abort_callback &aborter)
 
static void fileSanitySeek (file::ptr f, pfc::array_t< uint8_t > const &content, size_t offset, abort_callback &aborter)
 

Function Documentation

bool fb2kFileSelfTest ( file::ptr  f,
abort_callback aborter 
)

Debug self-test function for testing a file object implementation, performs various behavior validity checks, random access etc. Output goes to fb2k console. Returns true on success, false on failure (buggy file object implementation).

Definition at line 139 of file filesystem_helper.cpp.

139  {
140  try {
141  pfc::array_t<uint8_t> fileContent;
142  f->reopen(aborter);
143  f->read_till_eof(fileContent, aborter);
144 
145  {
146  t_filesize sizeClaimed = f->get_size(aborter);
147  if (sizeClaimed == filesize_invalid) {
148  FB2K_console_formatter() << "File sanity: file reports unknown size, actual size read is " << fileContent.get_size();
149  }
150  else {
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");
154  }
155  else {
156  FB2K_console_formatter() << "File sanity: file size check OK: " << sizeClaimed;
157  }
158  }
159  }
160 
161  {
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);
165  buf1.set_size_discard(sizeUpTo);
166 
167  for (size_t w = 1; w <= sizeUpTo; w <<= 1) {
168  f->reopen(aborter);
169  size_t did = f->read(buf1.get_ptr(), w, aborter);
170  if (did != w) {
171  FB2K_console_formatter() << "File sanity: premature EOF reading first " << w << " bytes, got " << did;
172  throw std::runtime_error("Premature EOF");
173  }
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");
177  }
178  }
179  }
180  if (f->can_seek()) {
181  FB2K_console_formatter() << "File sanity: testing random access...";
182 
183  {
184  size_t sizeUpTo = pfc::min_t<size_t>(fileContent.get_size(), 1024 * 1024);
185  for (size_t w = 1; w < sizeUpTo; w <<= 1) {
186  fileSanitySeek(f, fileContent, w, aborter);
187  }
188  fileSanitySeek(f, fileContent, fileContent.get_size(), aborter);
189  for (size_t w = 1; w < sizeUpTo; w <<= 1) {
190  fileSanitySeek(f, fileContent, fileContent.get_size() - w, aborter);
191  }
192  fileSanitySeek(f, fileContent, fileContent.get_size() / 2, aborter);
193  }
194  }
195  FB2K_console_formatter() << "File sanity test: all OK";
196  return true;
197  }
198  catch (std::exception const & e) {
199  FB2K_console_formatter() << "File sanity test failure: " << e.what();
200  return false;
201  }
202 }
const t_item * get_ptr() const
Definition: array.h:213
Special simplififed version of array class that avoids stepping on landmines with classes without pub...
Definition: array.h:11
static const t_filesize filesize_invalid
Invalid/unknown file size constant. Also see: t_filesize.
Definition: filesystem.h:16
std::exception exception
Definition: primitives.h:193
t_uint64 t_filesize
Type used for file size related variables.
Definition: filesystem.h:8
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)
Definition: array.h:36
t_size get_size() const
Definition: array.h:130
static void fileSanitySeek ( file::ptr  f,
pfc::array_t< uint8_t > const &  content,
size_t  offset,
abort_callback aborter 
)
static

Definition at line 111 of file filesystem_helper.cpp.

111  {
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");
119  }
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");
127  }
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");
131  }
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");
136  }
137 }
const t_item * get_ptr() const
Definition: array.h:52
const t_item * get_ptr() const
Definition: array.h:213
Special simplififed version of array class that avoids stepping on landmines with classes without pub...
Definition: array.h:11
t_uint64 t_filesize
Type used for file size related variables.
Definition: filesystem.h:8
void set_size_discard(t_size p_size)
Definition: array.h:36
t_size get_size() const
Definition: array.h:130