48 const std::string& line_) {
50 line_.begin(), line_.end(), [](
char c_) { return std::isspace(c_); });
53 std::string::size_type searchForSeparator(
54 const std::string& line_) {
56 const std::string::size_type length_(line_.size());
57 for(std::string::size_type i_(0); i_ < length_; ++i_) {
69 return std::string::npos;
72 std::string escapeKey(
73 const std::string& unescaped_key_) {
74 std::ostringstream oss_;
75 for(
char c_ : unescaped_key_) {
76 if(c_ ==
':' || c_ ==
'\\' || std::isspace(c_))
83 std::string unescapeKey(
84 const std::string& escaped_key_) {
85 std::ostringstream oss_;
87 for(
char c_ : escaped_key_) {
106 struct TestMarkStorage::Impl {
107 TestMarkFactory* factory;
108 std::string storage_file;
110 typedef std::map<std::string, TestMarkPtr> Storage;
116 const Impl&) =
delete;
118 const Impl&) =
delete;
121 TestMarkFactory* factory_,
122 const std::string& storage_file_);
126 TestMarkStorage::Impl::Impl(
127 TestMarkFactory* factory_,
128 const std::string& storage_file_) :
130 storage_file(storage_file_),
133 assert(factory !=
nullptr);
136 std::ifstream ifs_(storage_file.c_str());
138 std::ostringstream oss_;
139 ifs_.get(*oss_.rdbuf());
141 std::string line_(oss_.str());
144 if(isLineEmpty(line_))
148 auto sep_index_(searchForSeparator(line_));
149 if(sep_index_ <= 0 || sep_index_ == std::string::npos)
150 throw ExcTestMarkIn(
"invalid format of the test mark storage file " + storage_file);
151 std::string key_(line_.data(), line_.data() + sep_index_);
154 std::istrstream iss_(
155 line_.data() + sep_index_ + 1, line_.size() - sep_index_ - 1);
156 Base64IStream base64i_(&iss_);
157 Bzip2IStream bzip2i_(&base64i_);
158 TestMarkInBinIOS reader_(&bzip2i_);
162 storage.insert({unescapeKey(key_), testmark_});
166 TestMarkStorage::Impl::~Impl() {
169 std::ofstream ofs_(storage_file.c_str());
170 for(
const auto& mark_ : storage) {
172 ofs_ << escapeKey(mark_.first) <<
':';
176 Base64OStream base64o_(&ofs_);
177 Bzip2OStream bzip2o_(&base64o_);
178 TestMarkOutBinIOS writer_(&bzip2o_);
179 mark_.second->serializeMark(writer_);
190 const std::string& storage_file_) :
191 pimpl(new Impl(factory_, storage_file_)) {
200 const std::string& key_,
202 assert(!key_.empty() && test_mark_ !=
nullptr);
204 pimpl->storage[key_] = test_mark_;
205 pimpl->changed =
true;
209 const std::string& key_)
const {
210 assert(!key_.empty());
212 auto iter_(pimpl->storage.find(key_));
213 if(iter_ != pimpl->storage.end())
214 return (*iter_).second;