ChipMaster's trial hacks on C++CMS starting with v1.2.1. Not sure I'll follow on with the v2 since it looks to be breaking and mostly frivolous.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

193 lines
3.4 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
  4. //
  5. // See accompanying file COPYING.TXT file for licensing details.
  6. //
  7. ///////////////////////////////////////////////////////////////////////////////
  8. #define CPPCMS_SOURCE
  9. #include <cppcms/http_file.h>
  10. #include <cppcms/urandom.h>
  11. #include <cppcms/cppcms_error.h>
  12. #include <booster/nowide/cstdio.h>
  13. #include <booster/nowide/fstream.h>
  14. #include <stdlib.h>
  15. #include <iostream>
  16. #include "http_file_buffer.h"
  17. namespace cppcms {
  18. namespace http {
  19. struct file::impl_data {
  20. impl::file_buffer fb;
  21. std::istream in;
  22. std::ostream out;
  23. impl_data() :
  24. in(&fb),
  25. out(&fb)
  26. {
  27. }
  28. };
  29. std::string file::name() const
  30. {
  31. return name_;
  32. }
  33. std::string file::mime() const
  34. {
  35. return mime_;
  36. }
  37. bool file::has_mime() const
  38. {
  39. return !mime_.empty();
  40. }
  41. std::string file::filename() const
  42. {
  43. return filename_;
  44. }
  45. long long file::size()
  46. {
  47. return d->fb.size();
  48. }
  49. std::istream &file::data()
  50. {
  51. return d->in;
  52. }
  53. std::ostream &file::write_data()
  54. {
  55. return d->out;
  56. }
  57. void file::make_permanent()
  58. {
  59. file_temporary_ = 0;
  60. }
  61. void file::output_file(std::string const &name,bool is_temporary)
  62. {
  63. d->fb.name(name);
  64. if(!is_temporary) {
  65. if(d->fb.to_file()!=0) {
  66. throw cppcms_error("Failed to write to file " + name);
  67. }
  68. }
  69. file_specified_ = 1;
  70. file_temporary_ = is_temporary ? 1:0;
  71. }
  72. void file::copy_stream(std::istream &in,std::ostream &out)
  73. {
  74. out << in.rdbuf();
  75. }
  76. void file::save_to(std::string const &filename)
  77. {
  78. d->in.clear();
  79. d->in.seekg(0);
  80. d->fb.pubsync();
  81. if(d->fb.in_memory()) {
  82. save_by_copy(filename,d->in);
  83. return;
  84. }
  85. #ifdef CPPCMS_WIN32
  86. d->fb.close();
  87. /// we can't move opened file on windows as it would be locked
  88. if(booster::nowide::rename(d->fb.name().c_str(),filename.c_str())!=0) {
  89. booster::nowide::ifstream tmp(d->fb.name().c_str(),std::ios_base::binary | std::ios_base::in);
  90. if(!tmp) {
  91. throw cppcms_error("Failed to reopen file");
  92. }
  93. save_by_copy(filename,tmp);
  94. tmp.close();
  95. booster::nowide::remove(d->fb.name().c_str());
  96. }
  97. #else
  98. if(booster::nowide::rename(d->fb.name().c_str(),filename.c_str())!=0) {
  99. save_by_copy(filename,d->in);
  100. booster::nowide::remove(d->fb.name().c_str());
  101. }
  102. d->fb.close();
  103. #endif
  104. removed_ = 1;
  105. }
  106. void file::save_by_copy(std::string const &file_name,std::istream &in)
  107. {
  108. booster::nowide::ofstream f(file_name.c_str(),std::ios_base::binary | std::ios_base::out);
  109. if(!f) {
  110. throw cppcms_error("Failed to save open file:"+file_name);
  111. }
  112. copy_stream(in,f);
  113. f << std::flush;
  114. f.close();
  115. }
  116. void file::set_memory_limit(size_t size)
  117. {
  118. d->fb.set_limit(size);
  119. }
  120. void file::set_temporary_directory(std::string const &dir)
  121. {
  122. d->fb.temp_dir(dir);
  123. }
  124. file::file() :
  125. removed_(0),
  126. file_specified_(0),
  127. file_temporary_(1),
  128. d(new impl_data())
  129. {
  130. }
  131. int file::close()
  132. {
  133. if(!d->fb.in_memory() && !removed_) {
  134. int r = d->fb.close();
  135. if(file_temporary_ && !d->fb.name().empty()) {
  136. booster::nowide::remove(d->fb.name().c_str());
  137. removed_ = 1;
  138. }
  139. return r;
  140. }
  141. else
  142. return d->fb.close();
  143. }
  144. file::~file()
  145. {
  146. close();
  147. }
  148. void file::filename(std::string const &v)
  149. {
  150. filename_=v;
  151. }
  152. void file::name(std::string const &v)
  153. {
  154. name_=v;
  155. }
  156. void file::mime(std::string const &v)
  157. {
  158. mime_=v;
  159. }
  160. } // http
  161. } // cppcms