susumu.yata
null+****@clear*****
Fri Sep 26 15:45:06 JST 2014
susumu.yata 2014-09-26 15:45:06 +0900 (Fri, 26 Sep 2014) New Revision: 4076edb73a7cfe65d8acfe73f1115d085f8f6217 https://github.com/groonga/grnxx/commit/4076edb73a7cfe65d8acfe73f1115d085f8f6217 Message: Fix a bug that String::append() fails to append itself. (#75) Modified files: include/grnxx/types/string.hpp lib/grnxx/types.cpp Modified: include/grnxx/types/string.hpp (+7 -1) =================================================================== --- include/grnxx/types/string.hpp 2014-09-26 15:30:18 +0900 (39e8eae) +++ include/grnxx/types/string.hpp 2014-09-26 15:45:06 +0900 (f27353a) @@ -312,7 +312,11 @@ class String { bool append(Error *error, const StringCRef &arg) { if ((size_ + arg.size()) > capacity_) { - if (!resize_buf(error, (size_ + arg.size()))) { + if ((arg.data() >= buf_.get()) && (arg.data() < (buf_.get() + size_))) { + // Note that "arg" will be deleted in resize_buf() if "arg" is a part + // of "*this". + return append_overlap(error, arg); + } else if (!resize_buf(error, (size_ + arg.size()))) { return false; } } @@ -393,6 +397,8 @@ class String { // Assume new_size > capacity_. bool resize_buf(Error *error, Int new_size); + // Resize the internal buffer and append a part of "*this". + bool append_overlap(Error *error, const StringCRef &arg); }; // Compare a null-terminated string with a string. Modified: lib/grnxx/types.cpp (+20 -2) =================================================================== --- lib/grnxx/types.cpp 2014-09-26 15:30:18 +0900 (7ceca95) +++ lib/grnxx/types.cpp 2014-09-26 15:45:06 +0900 (a0e0295) @@ -45,8 +45,7 @@ bool String::resize_buf(Error *error, Int new_size) { if (new_size > new_capacity) { new_capacity = new_size; } - Int new_buf_size = new_capacity; - unique_ptr<char[]> new_buf(new (nothrow) char[new_buf_size]); + unique_ptr<char[]> new_buf(new (nothrow) char[new_capacity]); if (!new_buf) { GRNXX_ERROR_SET(error, NO_MEMORY, "Memory allocation failed"); return false; @@ -57,6 +56,25 @@ bool String::resize_buf(Error *error, Int new_size) { return true; } +bool String::append_overlap(Error *error, const StringCRef &arg) { + Int new_capacity = capacity_ * 2; + Int new_size = size_ + arg.size(); + if (new_size > new_capacity) { + new_capacity = new_size; + } + unique_ptr<char[]> new_buf(new (nothrow) char[new_capacity]); + if (!new_buf) { + GRNXX_ERROR_SET(error, NO_MEMORY, "Memory allocation failed"); + return false; + } + std::memcpy(new_buf.get(), buf_.get(), size_); + std::memcpy(new_buf.get() + size_, arg.data(), arg.size()); + buf_ = std::move(new_buf); + size_ = new_size; + capacity_ = new_capacity; + return true; +} + DBOptions::DBOptions() {} TableOptions::TableOptions() {} -------------- next part -------------- HTML����������������������������...Download