Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(112)

Unified Diff: ui/base/x/selection_utils.cc

Issue 17029020: linux_aura: Redo how memory is handled in clipboard/drag code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/base/x/selection_utils.cc
diff --git a/ui/base/x/selection_utils.cc b/ui/base/x/selection_utils.cc
index 5dd6f681ce129ab01388a4068fcd5154410dffc5..f89bc6ced6a6624a433c64d64a08e36606742d67 100644
--- a/ui/base/x/selection_utils.cc
+++ b/ui/base/x/selection_utils.cc
@@ -58,56 +58,70 @@ void GetAtomIntersection(const std::vector< ::Atom>& one,
}
}
-///////////////////////////////////////////////////////////////////////////////
-
-SelectionFormatMap::SelectionFormatMap() {}
+void AddString16ToVector(const string16& str,
+ std::vector<unsigned char>* bytes) {
+ const unsigned char* front =
+ reinterpret_cast<const unsigned char*>(str.data());
+ bytes->insert(bytes->end(), front, front + (str.size() * 2));
+}
-SelectionFormatMap::~SelectionFormatMap() {
- // WriteText() inserts the same pointer multiple times for different
- // representations; we need to dedupe it.
- std::set<char*> to_delete;
- for (InternalMap::iterator it = data_.begin(); it != data_.end(); ++it)
- to_delete.insert(it->second.first);
+std::string RefCountedMemoryToString(
+ const scoped_refptr<base::RefCountedMemory>& memory) {
+ if (!memory) {
+ NOTREACHED();
+ return std::string();
+ }
- for (std::set<char*>::iterator it = to_delete.begin(); it != to_delete.end();
- ++it) {
- delete [] *it;
+ size_t size = memory->size();
+ if (!size) {
+ NOTREACHED();
sky 2013/06/24 20:36:18 Is an empty string not legal?
Elliot Glaysher 2013/06/24 20:54:35 I want to say that it's impossible, but I'm not ac
+ return std::string();
}
+
+ const unsigned char* front = memory->front();
+ return std::string(reinterpret_cast<const char*>(front), size);
}
-void SelectionFormatMap::Insert(::Atom atom, char* data, size_t size) {
- // Views code often inserts the same content multiple times, so we have to
- // free old data. Only call delete when it's the last pointer we have to that
- // data.
- InternalMap::iterator exists_it = data_.find(atom);
- if (exists_it != data_.end()) {
- int count = 0;
- for (InternalMap::iterator it = data_.begin(); it != data_.end(); ++it) {
- if (it->second.first == exists_it->second.first)
- count++;
- }
+string16 RefCountedMemoryToString16(
+ const scoped_refptr<base::RefCountedMemory>& memory) {
+ if (!memory) {
+ NOTREACHED();
+ return string16();
+ }
- if (count == 1)
- delete [] exists_it->second.first;
+ size_t size = memory->size();
+ if (!size) {
+ NOTREACHED();
+ return string16();
}
- data_.insert(std::make_pair(atom, std::make_pair(data, size)));
+ const unsigned char* front = memory->front();
+ return string16(reinterpret_cast<const base::char16*>(front), size / 2);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+SelectionFormatMap::SelectionFormatMap() {}
+
+SelectionFormatMap::~SelectionFormatMap() {}
+
+void SelectionFormatMap::Insert(
+ ::Atom atom,
+ const scoped_refptr<base::RefCountedMemory>& item) {
+ data_.insert(std::make_pair(atom, item));
}
-ui::SelectionData* SelectionFormatMap::GetFirstOf(
+ui::SelectionData SelectionFormatMap::GetFirstOf(
const std::vector< ::Atom>& requested_types) const {
for (std::vector< ::Atom>::const_iterator it = requested_types.begin();
it != requested_types.end(); ++it) {
const_iterator data_it = data_.find(*it);
if (data_it != data_.end()) {
- ui::SelectionData* data = new SelectionData;
- data->Set(data_it->first, data_it->second.first, data_it->second.second,
- false);
- return data;
+ return SelectionData(data_it->first, data_it->second);
}
}
- return NULL;
+ return SelectionData();
}
std::vector< ::Atom> SelectionFormatMap::GetTypes() const {
@@ -118,50 +132,60 @@ std::vector< ::Atom> SelectionFormatMap::GetTypes() const {
return atoms;
}
-scoped_ptr<SelectionFormatMap> SelectionFormatMap::Clone() const {
- scoped_ptr<SelectionFormatMap> ret(new SelectionFormatMap);
-
- for (const_iterator it = data_.begin(); it != data_.end(); ++it) {
- char* data_copy = new char[it->second.second];
- memcpy(data_copy, it->second.first, it->second.second);
- ret->Insert(it->first, data_copy, it->second.second);
- }
-
- return ret.Pass();
-}
-
///////////////////////////////////////////////////////////////////////////////
SelectionData::SelectionData()
: type_(None),
- data_(NULL),
- size_(0),
- owned_(false),
atom_cache_(ui::GetXDisplay(), kSelectionDataAtoms) {
}
-SelectionData::~SelectionData() {
- if (owned_)
- XFree(data_);
+SelectionData::SelectionData(
+ ::Atom type,
+ const scoped_refptr<base::RefCountedMemory>& memory)
+ : type_(type),
+ memory_(memory),
+ atom_cache_(ui::GetXDisplay(), kSelectionDataAtoms) {
+}
+
+SelectionData::SelectionData(const SelectionData& rhs)
+ : type_(rhs.type_),
+ memory_(rhs.memory_),
+ atom_cache_(ui::GetXDisplay(), kSelectionDataAtoms) {
+}
+
+SelectionData::~SelectionData() {}
+
+SelectionData& SelectionData::operator=(const SelectionData& rhs) {
+ type_ = rhs.type_;
+ memory_ = rhs.memory_;
+ // TODO(erg): In some future where we have to support multiple X Displays,
+ // the following will also need to deal with the display.
+ return *this;
+}
+
+bool SelectionData::IsValid() const {
+ return type_ != None;
}
-void SelectionData::Set(::Atom type, char* data, size_t size, bool owned) {
- if (owned_)
- XFree(data_);
+::Atom SelectionData::GetType() const {
+ return type_;
+}
- type_ = type;
- data_ = data;
- size_ = size;
- owned_ = owned;
+const unsigned char* SelectionData::GetData() const {
+ return memory_ ? memory_->front() : NULL;
+}
+
+size_t SelectionData::GetSize() const {
+ return memory_ ? memory_->size() : 0;
}
std::string SelectionData::GetText() const {
if (type_ == atom_cache_.GetAtom(kUtf8String) ||
type_ == atom_cache_.GetAtom(kText)) {
- return std::string(data_, size_);
+ return RefCountedMemoryToString(memory_);
} else if (type_ == atom_cache_.GetAtom(kString)) {
std::string result;
- base::ConvertToUtf8AndNormalize(std::string(data_, size_),
+ base::ConvertToUtf8AndNormalize(RefCountedMemoryToString(memory_),
base::kCodepageLatin1,
&result);
return result;
@@ -177,14 +201,17 @@ string16 SelectionData::GetHtml() const {
string16 markup;
if (type_ == atom_cache_.GetAtom(Clipboard::kMimeTypeHTML)) {
+ const unsigned char* data = GetData();
+ size_t size = GetSize();
+
// If the data starts with 0xFEFF, i.e., Byte Order Mark, assume it is
// UTF-16, otherwise assume UTF-8.
- if (size_ >= 2 &&
- reinterpret_cast<const uint16_t*>(data_)[0] == 0xFEFF) {
- markup.assign(reinterpret_cast<const uint16_t*>(data_) + 1,
- (size_ / 2) - 1);
+ if (size >= 2 &&
+ reinterpret_cast<const uint16_t*>(data)[0] == 0xFEFF) {
+ markup.assign(reinterpret_cast<const uint16_t*>(data) + 1,
+ (size / 2) - 1);
} else {
- UTF8ToUTF16(reinterpret_cast<const char*>(data_), size_, &markup);
+ UTF8ToUTF16(reinterpret_cast<const char*>(data), size, &markup);
}
// If there is a terminating NULL, drop it.
@@ -199,11 +226,11 @@ string16 SelectionData::GetHtml() const {
}
void SelectionData::AssignTo(std::string* result) const {
- result->assign(data_, size_);
+ *result = RefCountedMemoryToString(memory_);
}
void SelectionData::AssignTo(string16* result) const {
- result->assign(reinterpret_cast<base::char16*>(data_), size_ / 2);
+ *result = RefCountedMemoryToString16(memory_);
}
} // namespace ui

Powered by Google App Engine
This is Rietveld 408576698