PageRenderTime 80ms CodeModel.GetById 8ms RepoModel.GetById 1ms app.codeStats 0ms

/win32/shellext/DirectoryStatus.cpp

https://bitbucket.org/tortoisehg/hgtk/
C++ | 167 lines | 115 code | 38 blank | 14 comment | 29 complexity | cba733c49e134c0270164bf31e4e8747 MD5 | raw file
Possible License(s): GPL-2.0
  1. // Copyright (C) 2009 Adrian Buehlmann
  2. //
  3. // This program is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation, either version 2 of the License, or
  6. // (at your option) any later version.
  7. //
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. #include "stdafx.h"
  16. #include "DirectoryStatus.h"
  17. #include "Thgstatus.h"
  18. #include "TortoiseUtils.h"
  19. char DirectoryStatus::status(const std::string& relpath_) const
  20. {
  21. char res = 'C';
  22. bool added = false;
  23. bool modified = false;
  24. const std::string relpath = relpath_ + '/';
  25. for (V::const_iterator i = v_.begin(); i != v_.end(); ++i)
  26. {
  27. const E& e = *i;
  28. if (relpath_.empty() ||
  29. e.path_.compare(0, relpath.length(), relpath) == 0)
  30. {
  31. if (e.status_ == 'm' || e.status_ == 'r')
  32. {
  33. modified = true;
  34. break;
  35. }
  36. if (e.status_ == 'a')
  37. added = true;
  38. }
  39. }
  40. if (modified)
  41. res = 'M';
  42. else if (added)
  43. res = 'A';
  44. else
  45. res = 'C';
  46. return res;
  47. }
  48. int DirectoryStatus::read(const std::string& hgroot, const std::string& cwd)
  49. {
  50. v_.clear();
  51. noicons_ = false;
  52. std::string p = hgroot + "\\.hg\\thgstatus";
  53. FILE *f = fopenReadRenameAllowed(p.c_str());
  54. if (!f)
  55. {
  56. TDEBUG_TRACE("DirectoryStatus::read: can't open '" << p << "'");
  57. std::string p = (cwd.size() < hgroot.size() ? hgroot : cwd);
  58. Thgstatus::update(p);
  59. return 0;
  60. }
  61. DirectoryStatus::E e;
  62. int res = 1;
  63. const std::string noicons = "@@noicons";
  64. std::vector<char> vline(200);
  65. for (;;)
  66. {
  67. vline.clear();
  68. char t;
  69. for (;;)
  70. {
  71. if (fread(&t, sizeof(t), 1, f) != 1)
  72. goto close;
  73. if (t == '\n')
  74. break;
  75. vline.push_back(t);
  76. if (vline.size() > 1000)
  77. {
  78. res = 0;
  79. goto close;
  80. }
  81. }
  82. vline.push_back(0);
  83. std::string line = &vline[0];
  84. if (line.substr(0, noicons.size()) == noicons)
  85. {
  86. noicons_ = true;
  87. goto close;
  88. }
  89. if (line.empty())
  90. goto close;
  91. e.status_ = line[0];
  92. std::string path;
  93. if (line.size() > 1)
  94. {
  95. path = line.c_str() + 1;
  96. ::CharLower(const_cast<char*>(path.c_str()));
  97. }
  98. path.push_back('/');
  99. e.path_ = path;
  100. v_.push_back(e);
  101. }
  102. close:
  103. fclose(f);
  104. TDEBUG_TRACE("DirectoryStatus::read(" << hgroot << "): done. "
  105. << v_.size() << " entries read. noicons_ = " << noicons_ );
  106. return res;
  107. }
  108. struct CacheEntry
  109. {
  110. std::string hgroot_;
  111. DirectoryStatus ds_;
  112. bool readfailed_;
  113. unsigned tickcount_;
  114. CacheEntry(): readfailed_(false), tickcount_(0) {};
  115. };
  116. DirectoryStatus* DirectoryStatus::get(
  117. const std::string& hgroot, const std::string& cwd)
  118. {
  119. static CacheEntry ce;
  120. unsigned tc = GetTickCount();
  121. if (ce.hgroot_ != hgroot || (tc - ce.tickcount_) > 2000)
  122. {
  123. ce.hgroot_.clear();
  124. ce.readfailed_ = (ce.ds_.read(hgroot, cwd) == 0);
  125. ce.hgroot_ = hgroot;
  126. ce.tickcount_ = GetTickCount();
  127. }
  128. return (ce.readfailed_ ? 0 : &ce.ds_);
  129. }