#include #include #include #include #include #define FB file_back_buffer using std::size_t; namespace fs = std::filesystem; /// A temporary file name struct temp_file { inline temp_file(const temp_file& c) = delete; inline temp_file(temp_file&& m) : name(std::move(m.name)) { m._full_path.clear(); } inline temp_file() : name(uuid::generate().to_string()+"-s3"){} inline temp_file(const char* name) : name(name) {} inline temp_file(std::string&& name) : name(name) {} inline ~temp_file() { if(!_full_path.empty() && fs::exists(_full_path) ) { D_dprintf("tfile removing: %s", _full_path.c_str()); fs::remove(_full_path); } } inline const fs::path& full_path() const { if(_full_path.empty()) { _full_path = fs::absolute( fs::temp_directory_path() / name ); D_dprintf("tfile path: %s", _full_path.c_str()); } return _full_path; } inline const std::string& base_name() const { return name; } inline const fs::path* operator->() const { return &full_path(); } private: std::string name; mutable fs::path _full_path; }; struct FB::impl { size_t cap; temp_file file; fvec_t backing; }; FB::FB(size_t cap) : inner(std::make_unique()) { // Set cap inner->cap = cap; // Create then open `inner->file` if(!fvec_new(&inner->backing, inner->file->c_str())) panic("Failed to open backing for temp file buffer"); } FB::FB(file_back_buffer&& m) : inner(std::move(m.inner)){} FB::FB() : FB(DEFAULT_CAP){} FB::~FB() { fvec_close(&inner->backing); } void FB::push_buf(byte* buf, size_t len) { fvec_push_whole_buffer(&inner->backing, (void*)buf, len); } bool FB::back(byte* buf, size_t len) const { return !!fvec_get_whole_buffer(&inner->backing, (void*)buf, len); } bool FB::pop_n(size_t len) { return !!fvec_pop_end(&inner->backing, len); } extern "C" void _fb_run_tests() { file_vector test; int r0,r1=0; for(int i=0;i<10;i++) { D_dprintf("push: %d", (10-i)); test.push_back(10-i); r1+= (10-i); } D_dprintf("r1: %d", r1); r0=0; while(test.size()) { r0+=test.back(); D_dprintf("back: %d", test.back()); test.pop_back(); } D_dprintf("r0: %d", r0); if(r0!=r1) panic("fb failed test: %d, %d", r0, r1); D_dprintf("test successful"); }