@@ -64,6 +64,18 @@ namespace http { | |||
/// Get the size of the file. | |||
/// | |||
long long size(); | |||
/// | |||
/// Specify the path to the output file, note if is_temporary is true | |||
/// than the file would be deleted on cppcms::http::file destruction, | |||
/// unless save_to is called, otherwise it would remain persistent | |||
/// | |||
void output_file(std::string const &name,bool is_temporary = false); | |||
/// | |||
/// Make sure that file created by output_file member function is not removed in destructor | |||
/// | |||
void make_permanent(); | |||
/// | |||
/// Save file to file named \a filename. Throws cppcms_error in case of failure. | |||
@@ -85,35 +97,39 @@ namespace http { | |||
file(); | |||
~file(); | |||
/// \endcond | |||
/// | |||
/// Set the maximal size of file that would be stored in memory instead of file system | |||
/// | |||
void set_memory_limit(size_t size); | |||
/// | |||
/// Set the temporary directory where uploaded files are created | |||
/// | |||
void set_temporary_directory(std::string const &dir); | |||
/// \endcond | |||
private: | |||
void add_bytes_to_size(size_t n); | |||
friend class impl::multipart_parser; | |||
std::string name_; | |||
std::string mime_; | |||
std::string filename_; | |||
size_t size_limit_; | |||
booster::nowide::fstream file_; | |||
std::stringstream file_data_; | |||
std::string tmp_file_name_; | |||
std::string temporary_dir_; | |||
booster::nowide::fstream res1_; | |||
std::stringstream res2_; | |||
std::string res3_; | |||
std::string res4_; | |||
void move_to_file(); | |||
void save_by_copy(std::string const &file_name,std::istream &in); | |||
void copy_stream(std::istream &in,std::ostream &out); | |||
uint32_t saved_in_file_ : 1; | |||
uint32_t removed_ : 1 ; | |||
uint32_t reserverd_ : 30; | |||
uint32_t file_specified_ : 1; | |||
uint32_t file_temporary_: 1; | |||
uint32_t reserverd_ : 29; | |||
struct impl_data; // for future use | |||
booster::hold_ptr<impl_data> d; | |||
@@ -116,6 +116,21 @@ public: | |||
{ | |||
return file_size_ + (pptr() - pbase()); | |||
} | |||
int to_file() | |||
{ | |||
if(!in_memory_) | |||
return 0; | |||
size_t read_offset =gptr() - eback(); | |||
if(write_buffer() != 0) | |||
return -1; | |||
clear(data_); | |||
output_.resize(buffer_size); | |||
setp(&output_[0],&output_[0]+buffer_size); | |||
setg(0,0,0); | |||
read_offset_ = read_offset; | |||
in_memory_=false; | |||
return 0; | |||
} | |||
private: | |||
void get_name() | |||
@@ -237,18 +252,12 @@ protected: | |||
{ | |||
size_t size = pptr() - pbase(); | |||
if(in_memory_) { | |||
size_t read_offset =gptr() - eback(); | |||
if(size >= limit_) { | |||
if(write_buffer() != 0) | |||
if(to_file() < 0) | |||
return -1; | |||
clear(data_); | |||
output_.resize(buffer_size); | |||
setp(&output_[0],&output_[0]+buffer_size); | |||
setg(0,0,0); | |||
read_offset_ = read_offset; | |||
in_memory_=false; | |||
} | |||
else { | |||
size_t read_offset =gptr() - eback(); | |||
size_t new_size = data_.size() * 2; | |||
if(new_size == 0) | |||
new_size = 64; | |||
@@ -67,6 +67,24 @@ std::ostream &file::write_data() | |||
return d->out; | |||
} | |||
void file::make_permanent() | |||
{ | |||
file_temporary_ = 0; | |||
} | |||
void file::output_file(std::string const &name,bool is_temporary) | |||
{ | |||
d->fb.name(name); | |||
if(!is_temporary) { | |||
if(d->fb.to_file()!=0) { | |||
throw cppcms_error("Failed to write to file " + name); | |||
} | |||
} | |||
file_specified_ = 1; | |||
file_temporary_ = is_temporary ? 1:0; | |||
} | |||
void file::copy_stream(std::istream &in,std::ostream &out) | |||
{ | |||
out << in.rdbuf(); | |||
@@ -77,7 +95,7 @@ void file::save_to(std::string const &filename) | |||
d->in.clear(); | |||
d->in.seekg(0); | |||
d->fb.pubsync(); | |||
if(d->fb.in_memory()) { | |||
save_by_copy(filename,d->in); | |||
return; | |||
@@ -128,6 +146,8 @@ void file::set_temporary_directory(std::string const &dir) | |||
file::file() : | |||
removed_(0), | |||
file_specified_(0), | |||
file_temporary_(1), | |||
d(new impl_data()) | |||
{ | |||
} | |||
@@ -136,7 +156,7 @@ file::~file() | |||
{ | |||
if(!d->fb.in_memory() && !removed_) { | |||
d->fb.close(); | |||
if(!d->fb.name().empty()) { | |||
if(file_temporary_ && !d->fb.name().empty()) { | |||
booster::nowide::remove(d->fb.name().c_str()); | |||
} | |||
} | |||