foobar2000 SDK  2015-01-14
filesystem.h
Go to the documentation of this file.
1 class file_info;
2 
4 
5 namespace foobar2000_io
6 {
14  const t_filetimestamp filetimestamp_invalid = 0;
16  static const t_filesize filesize_invalid = (t_filesize)(~0);
17 
18  static const t_filetimestamp filetimestamp_1second_increment = 10000000;
19 
21  PFC_DECLARE_EXCEPTION(exception_io, pfc::exception,"I/O error");
23  PFC_DECLARE_EXCEPTION(exception_io_not_found, exception_io,"Object not found");
25  PFC_DECLARE_EXCEPTION(exception_io_denied, exception_io,"Access denied");
27  PFC_DECLARE_EXCEPTION(exception_io_denied_readonly, exception_io_denied,"File is read-only");
29  PFC_DECLARE_EXCEPTION(exception_io_data, exception_io,"Unsupported format or corrupted file");
31  PFC_DECLARE_EXCEPTION(exception_io_data_truncation, exception_io_data,"Unsupported format or corrupted file");
33  PFC_DECLARE_EXCEPTION(exception_io_unsupported_format, exception_io_data,"Unsupported file format");
35  PFC_DECLARE_EXCEPTION(exception_io_object_is_remote, exception_io,"This operation is not supported on remote objects");
37  PFC_DECLARE_EXCEPTION(exception_io_sharing_violation, exception_io,"File is already in use");
39  PFC_DECLARE_EXCEPTION(exception_io_device_full, exception_io,"Device full");
41  PFC_DECLARE_EXCEPTION(exception_io_seek_out_of_range, exception_io,"Seek offset out of range");
43  PFC_DECLARE_EXCEPTION(exception_io_object_not_seekable, exception_io,"Object is not seekable");
45  PFC_DECLARE_EXCEPTION(exception_io_no_length, exception_io,"Length of object is unknown");
47  PFC_DECLARE_EXCEPTION(exception_io_no_handler_for_path, exception_io,"Invalid path");
49  PFC_DECLARE_EXCEPTION(exception_io_already_exists, exception_io,"Object already exists");
51  PFC_DECLARE_EXCEPTION(exception_io_no_data, exception_io,"The process receiving or sending data has terminated");
53  PFC_DECLARE_EXCEPTION(exception_io_network_not_reachable,exception_io,"Network not reachable");
55  PFC_DECLARE_EXCEPTION(exception_io_write_protected, exception_io_denied,"The media is write protected");
57  PFC_DECLARE_EXCEPTION(exception_io_file_corrupted, exception_io,"The file is corrupted");
59  PFC_DECLARE_EXCEPTION(exception_io_disk_change, exception_io,"Disc not available");
61  PFC_DECLARE_EXCEPTION(exception_io_directory_not_empty, exception_io,"Directory not empty");
62 
64  struct t_filestats {
66  t_filesize m_size;
68  t_filetimestamp m_timestamp;
69 
70  inline bool operator==(const t_filestats & param) const {return m_size == param.m_size && m_timestamp == param.m_timestamp;}
71  inline bool operator!=(const t_filestats & param) const {return m_size != param.m_size || m_timestamp != param.m_timestamp;}
72  };
73 
75  static const t_filestats filestats_invalid = {filesize_invalid,filetimestamp_invalid};
76 
77 #ifdef _WIN32
78  PFC_NORETURN void exception_io_from_win32(DWORD p_code);
79 #define WIN32_IO_OP(X) {SetLastError(NO_ERROR); if (!(X)) exception_io_from_win32(GetLastError());}
80 
81  // SPECIAL WORKAROUND: throw "file is read-only" rather than "access denied" where appropriate
82  PFC_NORETURN void win32_file_write_failure(DWORD p_code, const char * path);
83 #endif
84 
87  class NOVTABLE stream_reader {
88  public:
94  virtual t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) = 0;
99  virtual void read_object(void * p_buffer,t_size p_bytes,abort_callback & p_abort);
104  virtual t_filesize skip(t_filesize p_bytes,abort_callback & p_abort);
108  virtual void skip_object(t_filesize p_bytes,abort_callback & p_abort);
109 
113  template<typename T> inline void read_object_t(T& p_object,abort_callback & p_abort) {pfc::assert_raw_type<T>(); read_object(&p_object,sizeof(p_object),p_abort);}
117  template<typename T> inline void read_lendian_t(T& p_object,abort_callback & p_abort) {read_object_t(p_object,p_abort); byte_order::order_le_to_native_t(p_object);}
121  template<typename T> inline void read_bendian_t(T& p_object,abort_callback & p_abort) {read_object_t(p_object,p_abort); byte_order::order_be_to_native_t(p_object);}
122 
124  void read_string(pfc::string_base & p_out,abort_callback & p_abort);
126  void read_string_raw(pfc::string_base & p_out,abort_callback & p_abort);
128  pfc::string read_string(abort_callback & p_abort);
129 
131  void read_string_ex(pfc::string_base & p_out,t_size p_bytes,abort_callback & p_abort);
133  pfc::string read_string_ex(t_size p_len,abort_callback & p_abort);
134 
135  void read_string_nullterm( pfc::string_base & out, abort_callback & abort );
136 
137  t_filesize skip_till_eof(abort_callback & abort);
138 
139  template<typename t_outArray>
140  void read_till_eof(t_outArray & out, abort_callback & abort) {
141  pfc::assert_raw_type<typename t_outArray::t_item>();
142  const t_size itemWidth = sizeof(typename t_outArray::t_item);
143  out.set_size(pfc::max_t<t_size>(1,256 / itemWidth)); t_size done = 0;
144  for(;;) {
145  t_size delta = out.get_size() - done;
146  t_size delta2 = read(out.get_ptr() + done, delta * itemWidth, abort ) / itemWidth;
147  done += delta2;
148  if (delta2 != delta) break;
149  out.set_size(out.get_size() << 1);
150  }
151  out.set_size(done);
152  }
153  protected:
156  };
157 
158 
161  class NOVTABLE stream_writer {
162  public:
167  virtual void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) = 0;
168 
170  inline void write_object(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) {write(p_buffer,p_bytes,p_abort);}
171 
175  template<typename T> inline void write_object_t(const T & p_object, abort_callback & p_abort) {pfc::assert_raw_type<T>(); write_object(&p_object,sizeof(p_object),p_abort);}
179  template<typename T> inline void write_lendian_t(const T & p_object, abort_callback & p_abort) {T temp = p_object; byte_order::order_native_to_le_t(temp); write_object_t(temp,p_abort);}
183  template<typename T> inline void write_bendian_t(const T & p_object, abort_callback & p_abort) {T temp = p_object; byte_order::order_native_to_be_t(temp); write_object_t(temp,p_abort);}
184 
186  void write_string(const char * p_string,abort_callback & p_abort);
187  void write_string(const char * p_string,t_size p_len,abort_callback & p_abort);
188 
189  template<typename T>
190  void write_string(const T& val,abort_callback & p_abort) {write_string(pfc::stringToPtr(val),p_abort);}
191 
193  void write_string_raw(const char * p_string,abort_callback & p_abort);
194 
195  void write_string_nullterm( const char * p_string, abort_callback & p_abort) {this->write( p_string, strlen(p_string)+1, p_abort); }
196  protected:
199  };
200 
203  class NOVTABLE file : public service_base, public stream_reader, public stream_writer {
204  public:
205 
207  enum t_seek_mode {
209  seek_from_beginning = 0,
211  seek_from_current = 1,
213  seek_from_eof = 2,
214  };
215 
219  virtual t_filesize get_size(abort_callback & p_abort) = 0;
220 
221 
225  virtual t_filesize get_position(abort_callback & p_abort) = 0;
226 
229  virtual void resize(t_filesize p_size,abort_callback & p_abort) = 0;
230 
234  virtual void seek(t_filesize p_position,abort_callback & p_abort) = 0;
235 
237  void seek_probe(t_filesize p_position, abort_callback & p_abort);
238 
243  virtual void seek_ex(t_sfilesize p_position,t_seek_mode p_mode,abort_callback & p_abort);
244 
246  virtual bool can_seek() = 0;
247 
250  virtual bool get_content_type(pfc::string_base & p_out) = 0;
251 
253  virtual bool is_in_memory() {return false;}
254 
257  virtual void on_idle(abort_callback & p_abort) {}
258 
262  virtual t_filetimestamp get_timestamp(abort_callback & p_abort) {return filetimestamp_invalid;}
263 
266  virtual void reopen(abort_callback & p_abort) = 0;
267 
269  virtual bool is_remote() = 0;
270 
272  t_filestats get_stats(abort_callback & p_abort);
273 
275  bool is_eof(abort_callback & p_abort);
276 
278  void truncate(t_filesize p_position,abort_callback & p_abort);
279 
281  void set_eof(abort_callback & p_abort) {resize(get_position(p_abort),p_abort);}
282 
283 
285  t_filesize get_size_ex(abort_callback & p_abort);
286 
288  t_filesize get_remaining(abort_callback & p_abort);
289 
291  void probe_remaining(t_filesize bytes, abort_callback & p_abort);
292 
294  void ensure_seekable();
295 
297  void ensure_local();
298 
301  static t_filesize g_transfer(stream_reader * src,stream_writer * dst,t_filesize bytes,abort_callback & p_abort);
303  static void g_transfer_object(stream_reader * src,stream_writer * dst,t_filesize bytes,abort_callback & p_abort);
305  static void g_transfer_file(const service_ptr_t<file> & p_from,const service_ptr_t<file> & p_to,abort_callback & p_abort);
306 
308  static t_filesize g_transfer(service_ptr_t<file> p_src,service_ptr_t<file> p_dst,t_filesize p_bytes,abort_callback & p_abort);
310  static void g_transfer_object(service_ptr_t<file> p_src,service_ptr_t<file> p_dst,t_filesize p_bytes,abort_callback & p_abort);
311 
312 
313  t_filesize skip(t_filesize p_bytes,abort_callback & p_abort);
314  t_filesize skip_seek(t_filesize p_bytes,abort_callback & p_abort);
315 
316  FB2K_MAKE_SERVICE_INTERFACE(file,service_base);
317  };
318 
320 
322  class file_dynamicinfo : public file {
324  public:
326  virtual bool get_static_info(class file_info & p_out) = 0;
328  virtual bool is_dynamic_info_enabled()=0;
330  virtual bool get_dynamic_info(class file_info & p_out) = 0;
331  };
332 
334  class file_cached : public file {
336  public:
337  virtual size_t get_cache_block_size() = 0;
338  virtual void suggest_grow_cache(size_t suggestSize) = 0;
339 
340  static file::ptr g_create(service_ptr_t<file> p_base,abort_callback & p_abort, t_size blockSize);
341  static void g_create(service_ptr_t<file> & p_out,service_ptr_t<file> p_base,abort_callback & p_abort, t_size blockSize);
342 
343  static void g_decodeInitCache(file::ptr & theFile, abort_callback & abort, size_t blockSize);
344  };
345 
347  template<typename t_base> class file_readonly_t : public t_base {
348  public:
349  void resize(t_filesize p_size,abort_callback & p_abort) {throw exception_io_denied();}
350  void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) {throw exception_io_denied();}
351  };
353 
354  class file_streamstub : public file_readonly {
355  public:
356  t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) {return 0;}
357  t_filesize get_size(abort_callback & p_abort) {return filesize_invalid;}
358  t_filesize get_position(abort_callback & p_abort) {return 0;}
359  bool get_content_type(pfc::string_base & p_out) {return false;}
360  bool is_remote() {return true;}
362  void seek(t_filesize p_position,abort_callback & p_abort) {throw exception_io_object_not_seekable();}
363  bool can_seek() {return false;}
364  };
365 
366  class filesystem;
367 
368  class NOVTABLE directory_callback {
369  public:
371  virtual bool on_entry(filesystem * p_owner,abort_callback & p_abort,const char * p_url,bool p_is_subdirectory,const t_filestats & p_stats)=0;
372  };
373 
374 
378  class NOVTABLE filesystem : public service_base {
379  FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(filesystem);
380  public:
382  enum t_open_mode {
389  };
390 
391  virtual bool get_canonical_path(const char * p_path,pfc::string_base & p_out)=0;
392  virtual bool is_our_path(const char * p_path)=0;
393  virtual bool get_display_path(const char * p_path,pfc::string_base & p_out)=0;
394 
395  virtual void open(service_ptr_t<file> & p_out,const char * p_path, t_open_mode p_mode,abort_callback & p_abort)=0;
396  virtual void remove(const char * p_path,abort_callback & p_abort)=0;
397  virtual void move(const char * p_src,const char * p_dst,abort_callback & p_abort)=0;
399  virtual bool is_remote(const char * p_src) = 0;
400 
402  virtual void get_stats(const char * p_path,t_filestats & p_stats,bool & p_is_writeable,abort_callback & p_abort) = 0;
403 
404  virtual bool relative_path_create(const char * file_path,const char * playlist_path,pfc::string_base & out) {return false;}
405  virtual bool relative_path_parse(const char * relative_path,const char * playlist_path,pfc::string_base & out) {return false;}
406 
408  virtual void create_directory(const char * p_path,abort_callback & p_abort) = 0;
409 
410  virtual void list_directory(const char * p_path,directory_callback & p_out,abort_callback & p_abort)=0;
411 
414  virtual bool supports_content_types() = 0;
415 
416  static void g_get_canonical_path(const char * path,pfc::string_base & out);
417  static void g_get_display_path(const char * path,pfc::string_base & out);
420  static bool g_get_native_path( const char * path, pfc::string_base & out);
421 
422  static bool g_get_interface(service_ptr_t<filesystem> & p_out,const char * path);//path is AFTER get_canonical_path
423  static filesystem::ptr g_get_interface(const char * path);// throws exception_io_no_handler_for_path on failure
424  static bool g_is_remote(const char * p_path);//path is AFTER get_canonical_path
425  static bool g_is_recognized_and_remote(const char * p_path);//path is AFTER get_canonical_path
426  static bool g_is_remote_safe(const char * p_path) {return g_is_recognized_and_remote(p_path);}
427  static bool g_is_remote_or_unrecognized(const char * p_path);
428  static bool g_is_recognized_path(const char * p_path);
429 
431  static void g_open(service_ptr_t<file> & p_out,const char * p_path,t_open_mode p_mode,abort_callback & p_abort);
433  static void g_open_timeout(service_ptr_t<file> & p_out,const char * p_path,t_open_mode p_mode,double p_timeout,abort_callback & p_abort);
434  static void g_open_write_new(service_ptr_t<file> & p_out,const char * p_path,abort_callback & p_abort);
435  static void g_open_read(service_ptr_t<file> & p_out,const char * path,abort_callback & p_abort) {return g_open(p_out,path,open_mode_read,p_abort);}
436  static void g_open_precache(service_ptr_t<file> & p_out,const char * path,abort_callback & p_abort);//open only for precaching data (eg. will fail on http etc)
437  static bool g_exists(const char * p_path,abort_callback & p_abort);
438  static bool g_exists_writeable(const char * p_path,abort_callback & p_abort);
440  static void g_remove(const char * p_path,abort_callback & p_abort);
442  static void g_remove_timeout(const char * p_path,double p_timeout,abort_callback & p_abort);
444  static void g_move(const char * p_src,const char * p_dst,abort_callback & p_abort);
446  static void g_move_timeout(const char * p_src,const char * p_dst,double p_timeout,abort_callback & p_abort);
447 
448  static void g_link(const char * p_src,const char * p_dst,abort_callback & p_abort);
449  static void g_link_timeout(const char * p_src,const char * p_dst,double p_timeout,abort_callback & p_abort);
450 
451  static void g_copy(const char * p_src,const char * p_dst,abort_callback & p_abort);//needs canonical path
452  static void g_copy_timeout(const char * p_src,const char * p_dst,double p_timeout,abort_callback & p_abort);//needs canonical path
453  static void g_copy_directory(const char * p_src,const char * p_dst,abort_callback & p_abort);//needs canonical path
454  static void g_get_stats(const char * p_path,t_filestats & p_stats,bool & p_is_writeable,abort_callback & p_abort);
455  static bool g_relative_path_create(const char * p_file_path,const char * p_playlist_path,pfc::string_base & out);
456  static bool g_relative_path_parse(const char * p_relative_path,const char * p_playlist_path,pfc::string_base & out);
457 
458  static void g_create_directory(const char * p_path,abort_callback & p_abort);
459 
461  static FILE * streamio_open(const char * p_path,const char * p_flags);
462 
463  static void g_open_temp(service_ptr_t<file> & p_out,abort_callback & p_abort);
464  static void g_open_tempmem(service_ptr_t<file> & p_out,abort_callback & p_abort);
465  static file::ptr g_open_tempmem();
466 
467  static void g_list_directory(const char * p_path,directory_callback & p_out,abort_callback & p_abort);// path must be canonical
468 
469  static bool g_is_valid_directory(const char * path,abort_callback & p_abort);
470  static bool g_is_empty_directory(const char * path,abort_callback & p_abort);
471 
472  void remove_object_recur(const char * path, abort_callback & abort);
473  void remove_directory_content(const char * path, abort_callback & abort);
474  static void g_remove_object_recur(const char * path, abort_callback & abort);
475  static void g_remove_object_recur_timeout(const char * path, double timeout, abort_callback & abort);
476 
477  // Presumes both source and destination belong to this filesystem.
478  void copy_directory(const char * p_src, const char * p_dst, abort_callback & p_abort);
479  };
480 
482  {
483  struct t_entry
484  {
487  t_entry(const char * p_path, const t_filestats & p_stats) : m_path(p_path), m_stats(p_stats) {}
488  };
489 
490 
492  bool m_recur;
493 
495  public:
496  bool on_entry(filesystem * owner,abort_callback & p_abort,const char * url,bool is_subdirectory,const t_filestats & p_stats);
497 
498  directory_callback_impl(bool p_recur) : m_recur(p_recur) {}
499  t_size get_count() {return m_data.get_count();}
500  const char * operator[](t_size n) const {return m_data[n]->m_path;}
501  const char * get_item(t_size n) const {return m_data[n]->m_path;}
502  const t_filestats & get_item_stats(t_size n) const {return m_data[n]->m_stats;}
503  void sort() {m_data.sort_t(sortfunc);}
504  };
505 
506  class archive;
507 
508  class NOVTABLE archive_callback : public abort_callback {
509  public:
510  virtual bool on_entry(archive * owner,const char * url,const t_filestats & p_stats,const service_ptr_t<file> & p_reader) = 0;
511  };
512 
514  class NOVTABLE archive : public filesystem {
515  public:
516  virtual void archive_list(const char * p_path,const service_ptr_t<file> & p_reader,archive_callback & p_callback,bool p_want_readers) = 0;
517 
518  FB2K_MAKE_SERVICE_INTERFACE(archive,filesystem);
519  };
520 
522  class NOVTABLE archive_impl : public archive {
523  private:
524  //do not override these
525  bool get_canonical_path(const char * path,pfc::string_base & out);
526  bool is_our_path(const char * path);
527  bool get_display_path(const char * path,pfc::string_base & out);
528  void remove(const char * path,abort_callback & p_abort);
529  void move(const char * src,const char * dst,abort_callback & p_abort);
530  bool is_remote(const char * src);
531  bool relative_path_create(const char * file_path,const char * playlist_path,pfc::string_base & out);
532  bool relative_path_parse(const char * relative_path,const char * playlist_path,pfc::string_base & out);
533  void open(service_ptr_t<file> & p_out,const char * path, t_open_mode mode,abort_callback & p_abort);
534  void create_directory(const char * path,abort_callback &);
535  void list_directory(const char * p_path,directory_callback & p_out,abort_callback & p_abort);
536  void get_stats(const char * p_path,t_filestats & p_stats,bool & p_is_writeable,abort_callback & p_abort);
537  protected:
538  //override these
539  virtual const char * get_archive_type()=0;//eg. "zip", must be lowercase
540  virtual t_filestats get_stats_in_archive(const char * p_archive,const char * p_file,abort_callback & p_abort) = 0;
541  virtual void open_archive(service_ptr_t<file> & p_out,const char * archive,const char * file, abort_callback & p_abort)=0;//opens for reading
542  public:
543  //override these
544  virtual void archive_list(const char * path,const service_ptr_t<file> & p_reader,archive_callback & p_out,bool p_want_readers)=0;
545 
546 
547  static bool g_is_unpack_path(const char * path);
548  static bool g_parse_unpack_path(const char * path,pfc::string_base & archive,pfc::string_base & file);
549  static bool g_parse_unpack_path_ex(const char * path,pfc::string_base & archive,pfc::string_base & file, pfc::string_base & type);
550  static void g_make_unpack_path(pfc::string_base & path,const char * archive,const char * file,const char * type);
551  void make_unpack_path(pfc::string_base & path,const char * archive,const char * file);
552 
553 
554  };
555 
556  template<typename T>
558 
559 
560  t_filetimestamp filetimestamp_from_system_timer();
561 
562 #ifdef _WIN32
563  inline t_filetimestamp import_filetimestamp(FILETIME ft) {
564  return *reinterpret_cast<t_filetimestamp*>(&ft);
565  }
566 #endif
567 
568  void generate_temp_location_for_file(pfc::string_base & p_out, const char * p_origpath,const char * p_extension,const char * p_magic);
569 
570 
571  inline file_ptr fileOpen(const char * p_path,filesystem::t_open_mode p_mode,abort_callback & p_abort,double p_timeout) {
572  file_ptr temp; filesystem::g_open_timeout(temp,p_path,p_mode,p_timeout,p_abort); PFC_ASSERT(temp.is_valid()); return temp;
573  }
574 
575  inline file_ptr fileOpenReadExisting(const char * p_path,abort_callback & p_abort,double p_timeout = 0) {
576  return fileOpen(p_path,filesystem::open_mode_read,p_abort,p_timeout);
577  }
578  inline file_ptr fileOpenWriteExisting(const char * p_path,abort_callback & p_abort,double p_timeout = 0) {
579  return fileOpen(p_path,filesystem::open_mode_write_existing,p_abort,p_timeout);
580  }
581  inline file_ptr fileOpenWriteNew(const char * p_path,abort_callback & p_abort,double p_timeout = 0) {
582  return fileOpen(p_path,filesystem::open_mode_write_new,p_abort,p_timeout);
583  }
584 
585  template<typename t_list>
587  public:
588  directory_callback_retrieveList(t_list & p_list,bool p_getFiles,bool p_getSubDirectories) : m_list(p_list), m_getFiles(p_getFiles), m_getSubDirectories(p_getSubDirectories) {}
589  bool on_entry(filesystem * p_owner,abort_callback & p_abort,const char * p_url,bool p_is_subdirectory,const t_filestats & p_stats) {
590  p_abort.check();
591  if (p_is_subdirectory ? m_getSubDirectories : m_getFiles) {
592  m_list.add_item(p_url);
593  }
594  return true;
595  }
596  private:
598  const bool m_getFiles;
599  t_list & m_list;
600  };
601  template<typename t_list>
603  public:
604  directory_callback_retrieveListEx(t_list & p_files, t_list & p_directories) : m_files(p_files), m_directories(p_directories) {}
605  bool on_entry(filesystem * p_owner,abort_callback & p_abort,const char * p_url,bool p_is_subdirectory,const t_filestats & p_stats) {
606  p_abort.check();
607  if (p_is_subdirectory) m_directories += p_url;
608  else m_files += p_url;
609  return true;
610  }
611  private:
612  t_list & m_files;
613  t_list & m_directories;
614  };
615  template<typename t_list> class directory_callback_retrieveListRecur : public directory_callback {
616  public:
617  directory_callback_retrieveListRecur(t_list & p_list) : m_list(p_list) {}
618  bool on_entry(filesystem * owner,abort_callback & p_abort,const char * path, bool isSubdir, const t_filestats&) {
619  if (isSubdir) {
620  try { owner->list_directory(path,*this,p_abort); } catch(exception_io) {}
621  } else {
622  m_list.add_item(path);
623  }
624  return true;
625  }
626  private:
627  t_list & m_list;
628  };
629 
630  template<typename t_list>
631  static void listFiles(const char * p_path,t_list & p_out,abort_callback & p_abort) {
632  directory_callback_retrieveList<t_list> callback(p_out,true,false);
633  filesystem::g_list_directory(p_path,callback,p_abort);
634  }
635  template<typename t_list>
636  static void listDirectories(const char * p_path,t_list & p_out,abort_callback & p_abort) {
637  directory_callback_retrieveList<t_list> callback(p_out,false,true);
638  filesystem::g_list_directory(p_path,callback,p_abort);
639  }
640  template<typename t_list>
641  static void listFilesAndDirectories(const char * p_path,t_list & p_files,t_list & p_directories,abort_callback & p_abort) {
642  directory_callback_retrieveListEx<t_list> callback(p_files,p_directories);
643  filesystem::g_list_directory(p_path,callback,p_abort);
644  }
645  template<typename t_list>
646  static void listFilesRecur(const char * p_path,t_list & p_out,abort_callback & p_abort) {
648  filesystem::g_list_directory(p_path,callback,p_abort);
649  }
650 
651  bool extract_native_path(const char * p_fspath,pfc::string_base & p_native);
652  bool _extract_native_path_ptr(const char * & p_fspath);
653  bool is_native_filesystem( const char * p_fspath );
654  bool extract_native_path_ex(const char * p_fspath, pfc::string_base & p_native);//prepends \\?\ where needed
655 
656  template<typename T>
657  pfc::string getPathDisplay(const T& source) {
660  return temp.toString();
661  }
662  template<typename T>
663  pfc::string getPathCanonical(const T& source) {
666  return temp.toString();
667  }
668 
669 
670  bool matchContentType(const char * fullString, const char * ourType);
671  bool matchProtocol(const char * fullString, const char * protocolName);
672  void substituteProtocol(pfc::string_base & out, const char * fullString, const char * protocolName);
673 
674  void purgeOldFiles(const char * directory, t_filetimestamp period, abort_callback & abort);
675 }
676 
677 using namespace foobar2000_io;
678 
679 #include "filesystem_helper.h"
void read(const service_ptr_t< file > &p_file, abort_callback &p_abort, pfc::string_base &p_out, bool &is_utf8)
static file::ptr g_create(service_ptr_t< file > p_base, abort_callback &p_abort, t_size blockSize)
void write_string_nullterm(const char *p_string, abort_callback &p_abort)
Definition: filesystem.h:195
t_filesize get_size(HANDLE p_handle)
bool matchContentType(const char *fullString, const char *ourType)
service_ptr_t< file > file_ptr
Definition: filesystem.h:319
static void listFilesRecur(const char *p_path, t_list &p_out, abort_callback &p_abort)
Definition: filesystem.h:646
t_seek_mode
Seeking mode constants. Note: these are purposedly defined to same values as standard C SEEK_* consta...
Definition: filesystem.h:207
virtual void on_idle(abort_callback &p_abort)
Optional, called by owner thread before sleeping.
Definition: filesystem.h:257
t_int64 t_sfilesize
Type used for file size related variables when a signed value is needed.
Definition: filesystem.h:10
t_filesize m_size
Size of the file.
Definition: filesystem.h:66
void set_eof(abort_callback &p_abort)
Truncates the file at current read/write cursor position.
Definition: filesystem.h:281
const char * stringToPtr(T const &val)
Definition: string_base.h:1018
t_filetimestamp filetimestamp_from_system_timer()
Definition: filesystem.cpp:684
A class providing abstraction for an open file object, with reading/writing/seeking methods...
Definition: filesystem.h:203
static const t_filetimestamp filetimestamp_1second_increment
Definition: filesystem.h:18
PFC_NORETURN void win32_file_write_failure(DWORD p_code, const char *path)
Definition: filesystem.cpp:765
Opens an existing file for writing; if the file does not exist, the operation will fail...
Definition: filesystem.h:386
This class is used to signal underlying worker code whether user has decided to abort a potentially t...
void seek(HANDLE p_handle, t_sfilesize p_position, file::t_seek_mode p_mode)
bool get_content_type(pfc::string_base &p_out)
Definition: filesystem.h:359
virtual bool relative_path_create(const char *file_path, const char *playlist_path, pfc::string_base &out)
Definition: filesystem.h:404
pfc::string_simple m_path
Definition: filesystem.h:485
uint64_t t_uint64
Definition: int_types.h:3
static bool g_is_remote_safe(const char *p_path)
Definition: filesystem.h:426
static void g_get_canonical_path(const char *path, pfc::string_base &out)
Definition: filesystem.cpp:74
const char * get_item(t_size n) const
Definition: filesystem.h:501
PFC_NORETURN void exception_io_from_win32(DWORD p_code)
Definition: filesystem.cpp:773
bool extract_native_path_ex(const char *p_fspath, pfc::string_base &p_native)
Definition: filesystem.cpp:954
bool operator==(const t_filestats &param) const
Definition: filesystem.h:70
int compare(t1 const &p1, t2 const &p2)
Definition: pathUtils.h:29
t_filesize get_position(abort_callback &p_abort)
Definition: filesystem.h:358
pfc::string getPathDisplay(const T &source)
Definition: filesystem.h:657
bool _extract_native_path_ptr(const char *&p_fspath)
Definition: filesystem.cpp:942
void read_bendian_t(T &p_object, abort_callback &p_abort)
Helper template built around read_object. Reads single raw object from the stream; corrects byte orde...
Definition: filesystem.h:121
t_size read(void *p_buffer, t_size p_bytes, abort_callback &p_abort)
Definition: filesystem.h:356
const char * operator[](t_size n) const
Definition: filesystem.h:500
void order_native_to_le_t(T &param)
static int sortfunc(const pfc::rcptr_t< const t_entry > &p1, const pfc::rcptr_t< const t_entry > &p2)
Definition: filesystem.h:494
static const t_filesize filesize_invalid
Invalid/unknown file size constant. Also see: t_filesize.
Definition: filesystem.h:16
void check() const
Checks if user has requested the operation to be aborted, and throws exception_aborted if so...
static void listDirectories(const char *p_path, t_list &p_out, abort_callback &p_abort)
Definition: filesystem.h:636
bool is_native_filesystem(const char *p_fspath)
Definition: filesystem.cpp:938
static void g_open_read(service_ptr_t< file > &p_out, const char *path, abort_callback &p_abort)
Definition: filesystem.h:435
static void g_open_timeout(service_ptr_t< file > &p_out, const char *p_path, t_open_mode p_mode, double p_timeout, abort_callback &p_abort)
Attempts to open file at specified path; if the operation fails with sharing violation error...
Definition: filesystem.cpp:143
virtual void suggest_grow_cache(size_t suggestSize)=0
void order_be_to_native_t(T &param)
FB2K_MAKE_SERVICE_INTERFACE(file_cached, file)
Extension for cached file access - allows callers to know that they're dealing with a cache layer...
Definition: filesystem.h:334
PFC_DECLARE_EXCEPTION(exception_aborted, pfc::exception,"User abort")
Extension for shoutcast dynamic metadata handling.
Definition: filesystem.h:322
directory_callback_retrieveList(t_list &p_list, bool p_getFiles, bool p_getSubDirectories)
Definition: filesystem.h:588
static const t_filestats filestats_invalid
Invalid/unknown file stats constant. See: t_filestats.
Definition: filesystem.h:75
t_open_mode
Enumeration specifying how to open a file. See: filesystem::open(), filesystem::g_open().
Definition: filesystem.h:382
file_readonly_t< file > file_readonly
Definition: filesystem.h:352
file_ptr fileOpenWriteNew(const char *p_path, abort_callback &p_abort, double p_timeout=0)
Definition: filesystem.h:581
bool is_valid() const
Definition: service.h:119
virtual bool is_in_memory()
Hint, returns whether the file is already fully buffered into memory.
Definition: filesystem.h:253
Generic interface to read data from a nonseekable stream. Also see: stream_writer, file. Error handling: all methods may throw exception_io or one of derivatives on failure; exception_aborted when abort_callback is signaled.
Definition: filesystem.h:87
pfc::list_t< pfc::rcptr_t< t_entry > > m_data
Definition: filesystem.h:491
Interface for archive reader services. When implementing, derive from archive_impl rather than from d...
Definition: filesystem.h:514
static void g_list_directory(const char *p_path, directory_callback &p_out, abort_callback &p_abort)
Definition: filesystem.cpp:210
const t_filetimestamp filetimestamp_invalid
Invalid/unknown file timestamp constant. Also see: t_filetimestamp.
Definition: filesystem.h:14
Contains various I/O related structures and interfaces.
Definition: filetimetools.h:1
Main interface class for information about some playable object.
Definition: file_info.h:73
void read_lendian_t(T &p_object, abort_callback &p_abort)
Helper template built around read_object. Reads single raw object from the stream; corrects byte orde...
Definition: filesystem.h:117
t_filesize get_size(abort_callback &p_abort)
Definition: filesystem.h:357
void order_le_to_native_t(T &param)
string_simple_t< char > string_simple
Definition: string_base.h:824
const t_filestats & get_item_stats(t_size n) const
Definition: filesystem.h:502
size_t t_size
Definition: int_types.h:48
string8_fastalloc string_formatter
Definition: string_base.h:614
bool on_entry(filesystem *p_owner, abort_callback &p_abort, const char *p_url, bool p_is_subdirectory, const t_filestats &p_stats)
Definition: filesystem.h:589
t_entry(const char *p_path, const t_filestats &p_stats)
Definition: filesystem.h:487
bool matchProtocol(const char *fullString, const char *protocolName)
void seek(t_filesize p_position, abort_callback &p_abort)
Definition: filesystem.h:362
FB2K_MAKE_SERVICE_INTERFACE(file_dynamicinfo, file)
virtual bool get_dynamic_info(class file_info &p_out)=0
Retrieves dynamic stream info (e.g. online stream track titles). Returns true on success, false when info has not changed since last call.
Generic interface to write data to a nonseekable stream. Also see: stream_reader, file...
Definition: filesystem.h:161
Base class for all service classes. Provides interfaces for reference counter and querying for differ...
Definition: service.h:333
t_filetimestamp m_timestamp
Time of last file modification.
Definition: filesystem.h:68
bool extract_native_path(const char *p_fspath, pfc::string_base &p_native)
Definition: filesystem.cpp:948
Opens an existing file for reading; if the file does not exist, the operation will fail...
Definition: filesystem.h:384
void write(const void *p_buffer, t_size p_bytes, abort_callback &p_abort)
Definition: filesystem.h:350
void purgeOldFiles(const char *directory, t_filetimestamp period, abort_callback &abort)
Root class for archive implementations. Derive from this instead of from archive directly.
Definition: filesystem.h:522
bool on_entry(filesystem *owner, abort_callback &p_abort, const char *path, bool isSubdir, const t_filestats &)
Definition: filesystem.h:618
void write(const service_ptr_t< file > &p_file, abort_callback &p_abort, const char *p_string, bool is_utf8)
void generate_temp_location_for_file(pfc::string_base &p_out, const char *p_origpath, const char *p_extension, const char *p_magic)
Definition: filesystem.cpp:892
static void g_decodeInitCache(file::ptr &theFile, abort_callback &abort, size_t blockSize)
void read_till_eof(t_outArray &out, abort_callback &abort)
Definition: filesystem.h:140
virtual bool relative_path_parse(const char *relative_path, const char *playlist_path, pfc::string_base &out)
Definition: filesystem.h:405
void substituteProtocol(pfc::string_base &out, const char *fullString, const char *protocolName)
void resize(t_filesize p_size, abort_callback &p_abort)
Definition: filesystem.h:349
Entrypoint service for all filesystem operations. Implementation: standard implementations for local ...
Definition: filesystem.h:378
virtual size_t get_cache_block_size()=0
void write_lendian_t(const T &p_object, abort_callback &p_abort)
Helper template. Writes single raw object to the stream; corrects byte order assuming stream uses lit...
Definition: filesystem.h:179
t_uint64 t_filetimestamp
Type used for file timestamp related variables. 64-bit value representing the number of 100-nanosecon...
Definition: filesystem.h:12
virtual void list_directory(const char *p_path, directory_callback &p_out, abort_callback &p_abort)=0
bool on_entry(filesystem *p_owner, abort_callback &p_abort, const char *p_url, bool p_is_subdirectory, const t_filestats &p_stats)
Definition: filesystem.h:605
bool operator!=(const t_filestats &param) const
Definition: filesystem.h:71
void write_bendian_t(const T &p_object, abort_callback &p_abort)
Helper template. Writes single raw object to the stream; corrects byte order assuming stream uses big...
Definition: filesystem.h:183
static void g_get_display_path(const char *path, pfc::string_base &out)
Definition: filesystem.cpp:87
std::exception exception
Definition: primitives.h:193
static void listFilesAndDirectories(const char *p_path, t_list &p_files, t_list &p_directories, abort_callback &p_abort)
Definition: filesystem.h:641
Definition: filesystem.h:483
t_filetimestamp import_filetimestamp(FILETIME ft)
Definition: filesystem.h:563
t_uint64 t_filesize
Type used for file size related variables.
Definition: filesystem.h:8
void write_object_t(const T &p_object, abort_callback &p_abort)
Helper template. Writes single raw object to the stream.
Definition: filesystem.h:175
file_ptr fileOpenReadExisting(const char *p_path, abort_callback &p_abort, double p_timeout=0)
Definition: filesystem.h:575
Implementation helper - contains dummy implementations of methods that modify the file...
Definition: filesystem.h:347
New EXPERIMENTAL string class, allowing efficient copies and returning from functions. Does not implement the string_base interface so you still need string8 in many cases. Safe to pass between DLLs, but since a reference is used, objects possibly created by other DLLs must be released before owning DLLs are unloaded.
Definition: stringNew.h:19
virtual t_filetimestamp get_timestamp(abort_callback &p_abort)
Retrieves last modification time of the file.
Definition: filesystem.h:262
void write_string(const T &val, abort_callback &p_abort)
Definition: filesystem.h:190
Stores file stats (size and timestamp).
Definition: filesystem.h:64
void write_object(const void *p_buffer, t_size p_bytes, abort_callback &p_abort)
Helper. Same as write(), provided for consistency.
Definition: filesystem.h:170
void read_object_t(T &p_object, abort_callback &p_abort)
Helper template built around read_object. Reads single raw object from the stream.
Definition: filesystem.h:113
static void listFiles(const char *p_path, t_list &p_out, abort_callback &p_abort)
Definition: filesystem.h:631
void reopen(abort_callback &)
Definition: filesystem.h:361
t_filestats m_stats
Definition: filesystem.h:486
pfc::string getPathCanonical(const T &source)
Definition: filesystem.h:663
bool on_entry(filesystem *owner, abort_callback &p_abort, const char *url, bool is_subdirectory, const t_filestats &p_stats)
Definition: filesystem.cpp:488
virtual bool is_dynamic_info_enabled()=0
Returns whether dynamic info is available on this stream or not.
virtual bool get_static_info(class file_info &p_out)=0
Retrieves "static" info that doesn't change in the middle of stream, such as station names etc...
file_ptr fileOpen(const char *p_path, filesystem::t_open_mode p_mode, abort_callback &p_abort, double p_timeout)
Definition: filesystem.h:571
Opens a new file for writing; if the file exists, its contents will be wiped.
Definition: filesystem.h:388
int64_t t_int64
Definition: int_types.h:2
void order_native_to_be_t(T &param)
directory_callback_retrieveListEx(t_list &p_files, t_list &p_directories)
Definition: filesystem.h:604
file_ptr fileOpenWriteExisting(const char *p_path, abort_callback &p_abort, double p_timeout=0)
Definition: filesystem.h:578