selection_utils.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/x/selection_utils.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <set>
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/i18n/icu_string_conversions.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/clipboard/clipboard.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/x/x11_atom_cache.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/base/x/x11_util.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace ui {
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kMimeTypeMozillaURL[] = "text/x-moz-url";
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kString[] = "STRING";
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kText[] = "TEXT";
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kUtf8String[] = "UTF8_STRING";
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char* kSelectionDataAtoms[] = {
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Clipboard::kMimeTypeHTML,
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  kString,
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  kText,
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  kUtf8String,
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NULL
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::vector< ::Atom> GetTextAtomsFrom(const X11AtomCache* atom_cache) {
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector< ::Atom> atoms;
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  atoms.push_back(atom_cache->GetAtom(kString));
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  atoms.push_back(atom_cache->GetAtom(kText));
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  atoms.push_back(atom_cache->GetAtom(kUtf8String));
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return atoms;
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::vector< ::Atom> GetURLAtomsFrom(const X11AtomCache* atom_cache) {
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector< ::Atom> atoms;
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  atoms.push_back(atom_cache->GetAtom(Clipboard::kMimeTypeURIList));
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  atoms.push_back(atom_cache->GetAtom(kMimeTypeMozillaURL));
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return atoms;
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GetAtomIntersection(const std::vector< ::Atom>& one,
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         const std::vector< ::Atom>& two,
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         std::vector< ::Atom>* output) {
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (std::vector< ::Atom>::const_iterator it = one.begin(); it != one.end();
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       ++it) {
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (std::vector< ::Atom>::const_iterator jt = two.begin(); jt != two.end();
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         ++jt) {
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (*it == *jt) {
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        output->push_back(*it);
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid AddString16ToVector(const string16& str,
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                         std::vector<unsigned char>* bytes) {
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const unsigned char* front =
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      reinterpret_cast<const unsigned char*>(str.data());
65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bytes->insert(bytes->end(), front, front + (str.size() * 2));
66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::string RefCountedMemoryToString(
69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const scoped_refptr<base::RefCountedMemory>& memory) {
707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!memory.get()) {
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    NOTREACHED();
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return std::string();
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  size_t size = memory->size();
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!size)
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return std::string();
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const unsigned char* front = memory->front();
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return std::string(reinterpret_cast<const char*>(front), size);
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstring16 RefCountedMemoryToString16(
84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const scoped_refptr<base::RefCountedMemory>& memory) {
857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!memory.get()) {
86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    NOTREACHED();
87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return string16();
88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  size_t size = memory->size();
91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!size)
92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return string16();
93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const unsigned char* front = memory->front();
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return string16(reinterpret_cast<const base::char16*>(front), size / 2);
96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SelectionFormatMap::SelectionFormatMap() {}
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochSelectionFormatMap::~SelectionFormatMap() {}
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid SelectionFormatMap::Insert(
105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ::Atom atom,
106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const scoped_refptr<base::RefCountedMemory>& item) {
107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  data_.insert(std::make_pair(atom, item));
108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochui::SelectionData SelectionFormatMap::GetFirstOf(
111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::vector< ::Atom>& requested_types) const {
112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (std::vector< ::Atom>::const_iterator it = requested_types.begin();
113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch       it != requested_types.end(); ++it) {
114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const_iterator data_it = data_.find(*it);
115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (data_it != data_.end()) {
116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return SelectionData(data_it->first, data_it->second);
117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return SelectionData();
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::vector< ::Atom> SelectionFormatMap::GetTypes() const {
124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::vector< ::Atom> atoms;
125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (const_iterator it = data_.begin(); it != data_.end(); ++it)
126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    atoms.push_back(it->first);
127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return atoms;
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochSelectionData::SelectionData()
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : type_(None),
135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      atom_cache_(ui::GetXDisplay(), kSelectionDataAtoms) {
136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochSelectionData::SelectionData(
139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ::Atom type,
140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const scoped_refptr<base::RefCountedMemory>& memory)
141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    : type_(type),
142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      memory_(memory),
143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      atom_cache_(ui::GetXDisplay(), kSelectionDataAtoms) {
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochSelectionData::SelectionData(const SelectionData& rhs)
147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    : type_(rhs.type_),
148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      memory_(rhs.memory_),
149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      atom_cache_(ui::GetXDisplay(), kSelectionDataAtoms) {
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochSelectionData::~SelectionData() {}
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochSelectionData& SelectionData::operator=(const SelectionData& rhs) {
155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  type_ = rhs.type_;
156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  memory_ = rhs.memory_;
157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(erg): In some future where we have to support multiple X Displays,
158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // the following will also need to deal with the display.
159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return *this;
160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool SelectionData::IsValid() const {
163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return type_ != None;
164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch::Atom SelectionData::GetType() const {
167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return type_;
168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst unsigned char* SelectionData::GetData() const {
1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return memory_.get() ? memory_->front() : NULL;
172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochsize_t SelectionData::GetSize() const {
1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return memory_.get() ? memory_->size() : 0;
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string SelectionData::GetText() const {
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (type_ == atom_cache_.GetAtom(kUtf8String) ||
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      type_ == atom_cache_.GetAtom(kText)) {
181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return RefCountedMemoryToString(memory_);
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (type_ == atom_cache_.GetAtom(kString)) {
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string result;
184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::ConvertToUtf8AndNormalize(RefCountedMemoryToString(memory_),
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                    base::kCodepageLatin1,
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                    &result);
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return result;
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // BTW, I looked at COMPOUND_TEXT, and there's no way we're going to
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // support that. Yuck.
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    NOTREACHED();
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return std::string();
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)string16 SelectionData::GetHtml() const {
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  string16 markup;
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (type_ == atom_cache_.GetAtom(Clipboard::kMimeTypeHTML)) {
200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const unsigned char* data = GetData();
201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    size_t size = GetSize();
202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If the data starts with 0xFEFF, i.e., Byte Order Mark, assume it is
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // UTF-16, otherwise assume UTF-8.
205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (size >= 2 &&
206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        reinterpret_cast<const uint16_t*>(data)[0] == 0xFEFF) {
207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      markup.assign(reinterpret_cast<const uint16_t*>(data) + 1,
208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                    (size / 2) - 1);
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else {
210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      UTF8ToUTF16(reinterpret_cast<const char*>(data), size, &markup);
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If there is a terminating NULL, drop it.
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!markup.empty() && markup.at(markup.length() - 1) == '\0')
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      markup.resize(markup.length() - 1);
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return markup;
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    NOTREACHED();
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return markup;
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SelectionData::AssignTo(std::string* result) const {
225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  *result = RefCountedMemoryToString(memory_);
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SelectionData::AssignTo(string16* result) const {
229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  *result = RefCountedMemoryToString16(memory_);
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace ui
233