ArchiveStrategy.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. //
  2. // ArchiveStrategy.cpp
  3. //
  4. // Library: Foundation
  5. // Package: Logging
  6. // Module: FileChannel
  7. //
  8. // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
  9. // and Contributors.
  10. //
  11. // SPDX-License-Identifier: BSL-1.0
  12. //
  13. #include "Poco/ArchiveStrategy.h"
  14. #include "Poco/NumberFormatter.h"
  15. #include "Poco/File.h"
  16. #include "Poco/Path.h"
  17. #include "Poco/DeflatingStream.h"
  18. #include "Poco/StreamCopier.h"
  19. #include "Poco/Exception.h"
  20. #include "Poco/ActiveDispatcher.h"
  21. #include "Poco/ActiveMethod.h"
  22. #include "Poco/Void.h"
  23. #include "Poco/FileStream.h"
  24. namespace Poco {
  25. //
  26. // ArchiveCompressor
  27. //
  28. class ArchiveCompressor: public ActiveDispatcher
  29. {
  30. public:
  31. ArchiveCompressor():
  32. compress(this, &ArchiveCompressor::compressImpl)
  33. {
  34. }
  35. ~ArchiveCompressor()
  36. {
  37. }
  38. ActiveMethod<void, std::string, ArchiveCompressor, ActiveStarter<ActiveDispatcher>> compress;
  39. protected:
  40. void compressImpl(const std::string& path)
  41. {
  42. std::string gzPath(path);
  43. gzPath.append(".gz");
  44. FileInputStream istr(path);
  45. FileOutputStream ostr(gzPath);
  46. try
  47. {
  48. DeflatingOutputStream deflater(ostr, DeflatingStreamBuf::STREAM_GZIP);
  49. StreamCopier::copyStream(istr, deflater);
  50. if (!deflater.good() || !ostr.good()) throw WriteFileException(gzPath);
  51. deflater.close();
  52. ostr.close();
  53. istr.close();
  54. }
  55. catch (Poco::Exception&)
  56. {
  57. // deflating failed - remove gz file and leave uncompressed log file
  58. ostr.close();
  59. Poco::File gzf(gzPath);
  60. gzf.remove();
  61. return;
  62. }
  63. File f(path);
  64. f.remove();
  65. return;
  66. }
  67. };
  68. //
  69. // ArchiveStrategy
  70. //
  71. ArchiveStrategy::ArchiveStrategy():
  72. _compress(false),
  73. _pCompressor(0)
  74. {
  75. }
  76. ArchiveStrategy::~ArchiveStrategy()
  77. {
  78. delete _pCompressor;
  79. }
  80. void ArchiveStrategy::compress(bool flag)
  81. {
  82. _compress = flag;
  83. }
  84. void ArchiveStrategy::moveFile(const std::string& oldPath, const std::string& newPath)
  85. {
  86. bool compressed = false;
  87. Path p(oldPath);
  88. File f(oldPath);
  89. if (!f.exists())
  90. {
  91. f = oldPath + ".gz";
  92. compressed = true;
  93. }
  94. std::string mvPath(newPath);
  95. if (_compress || compressed)
  96. mvPath.append(".gz");
  97. if (!_compress || compressed)
  98. {
  99. f.renameTo(mvPath);
  100. }
  101. else
  102. {
  103. f.renameTo(newPath);
  104. if (!_pCompressor) _pCompressor = new ArchiveCompressor;
  105. _pCompressor.load()->compress(newPath);
  106. }
  107. }
  108. bool ArchiveStrategy::exists(const std::string& name)
  109. {
  110. File f(name);
  111. if (f.exists())
  112. {
  113. return true;
  114. }
  115. else if (_compress)
  116. {
  117. std::string gzName(name);
  118. gzName.append(".gz");
  119. File gzf(gzName);
  120. return gzf.exists();
  121. }
  122. else return false;
  123. }
  124. //
  125. // ArchiveByNumberStrategy
  126. //
  127. ArchiveByNumberStrategy::ArchiveByNumberStrategy()
  128. {
  129. }
  130. ArchiveByNumberStrategy::~ArchiveByNumberStrategy()
  131. {
  132. }
  133. LogFile* ArchiveByNumberStrategy::open(LogFile* pFile)
  134. {
  135. return pFile;
  136. }
  137. LogFile* ArchiveByNumberStrategy::archive(LogFile* pFile)
  138. {
  139. std::string basePath = pFile->path();
  140. delete pFile;
  141. int n = -1;
  142. std::string path;
  143. do
  144. {
  145. path = basePath;
  146. path.append(".");
  147. NumberFormatter::append(path, ++n);
  148. }
  149. while (exists(path));
  150. while (n >= 0)
  151. {
  152. std::string oldPath = basePath;
  153. if (n > 0)
  154. {
  155. oldPath.append(".");
  156. NumberFormatter::append(oldPath, n - 1);
  157. }
  158. std::string newPath = basePath;
  159. newPath.append(".");
  160. NumberFormatter::append(newPath, n);
  161. moveFile(oldPath, newPath);
  162. --n;
  163. }
  164. return new LogFile(basePath);
  165. }
  166. } // namespace Poco