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"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_util.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/clipboard/clipboard.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/base/x/x11_util.h"
1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/gfx/x/x11_atom_cache.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace ui {
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kMimeTypeMozillaURL[] = "text/x-moz-url";
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kString[] = "STRING";
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kText[] = "TEXT";
22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochconst char kTextPlain[] = "text/plain";
23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochconst char kTextPlainUtf8[] = "text/plain;charset=utf-8";
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kUtf8String[] = "UTF8_STRING";
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char* kSelectionDataAtoms[] = {
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Clipboard::kMimeTypeHTML,
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  kString,
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  kText,
30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  kTextPlain,
31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  kTextPlainUtf8,
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  kUtf8String,
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NULL
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::vector< ::Atom> GetTextAtomsFrom(const X11AtomCache* atom_cache) {
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector< ::Atom> atoms;
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  atoms.push_back(atom_cache->GetAtom(kUtf8String));
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  atoms.push_back(atom_cache->GetAtom(kString));
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  atoms.push_back(atom_cache->GetAtom(kText));
41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  atoms.push_back(atom_cache->GetAtom(kTextPlain));
42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  atoms.push_back(atom_cache->GetAtom(kTextPlainUtf8));
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return atoms;
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::vector< ::Atom> GetURLAtomsFrom(const X11AtomCache* atom_cache) {
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector< ::Atom> atoms;
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  atoms.push_back(atom_cache->GetAtom(Clipboard::kMimeTypeURIList));
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  atoms.push_back(atom_cache->GetAtom(kMimeTypeMozillaURL));
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return atoms;
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::vector< ::Atom> GetURIListAtomsFrom(const X11AtomCache* atom_cache) {
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector< ::Atom> atoms;
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  atoms.push_back(atom_cache->GetAtom(Clipboard::kMimeTypeURIList));
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return atoms;
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void GetAtomIntersection(const std::vector< ::Atom>& desired,
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                         const std::vector< ::Atom>& offered,
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         std::vector< ::Atom>* output) {
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (std::vector< ::Atom>::const_iterator it = desired.begin();
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       it != desired.end(); ++it) {
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    std::vector< ::Atom>::const_iterator jt =
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      std::find(offered.begin(), offered.end(), *it);
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (jt != offered.end())
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      output->push_back(*it);
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AddString16ToVector(const base::string16& str,
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                         std::vector<unsigned char>* bytes) {
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const unsigned char* front =
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      reinterpret_cast<const unsigned char*>(str.data());
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bytes->insert(bytes->end(), front, front + (str.size() * 2));
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::vector<std::string> ParseURIList(const SelectionData& data) {
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // uri-lists are newline separated file lists in URL encoding.
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string unparsed;
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  data.AssignTo(&unparsed);
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<std::string> tokens;
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Tokenize(unparsed, "\n", &tokens);
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return tokens;
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::string RefCountedMemoryToString(
89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const scoped_refptr<base::RefCountedMemory>& memory) {
907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!memory.get()) {
91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    NOTREACHED();
92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return std::string();
93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  size_t size = memory->size();
96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!size)
97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return std::string();
98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const unsigned char* front = memory->front();
100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return std::string(reinterpret_cast<const char*>(front), size);
101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 RefCountedMemoryToString16(
104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const scoped_refptr<base::RefCountedMemory>& memory) {
1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!memory.get()) {
106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    NOTREACHED();
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return base::string16();
108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  size_t size = memory->size();
111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!size)
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return base::string16();
113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const unsigned char* front = memory->front();
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return base::string16(reinterpret_cast<const base::char16*>(front), size / 2);
116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SelectionFormatMap::SelectionFormatMap() {}
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochSelectionFormatMap::~SelectionFormatMap() {}
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid SelectionFormatMap::Insert(
125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ::Atom atom,
126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const scoped_refptr<base::RefCountedMemory>& item) {
1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  data_.erase(atom);
128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  data_.insert(std::make_pair(atom, item));
129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochui::SelectionData SelectionFormatMap::GetFirstOf(
132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::vector< ::Atom>& requested_types) const {
133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (std::vector< ::Atom>::const_iterator it = requested_types.begin();
134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch       it != requested_types.end(); ++it) {
135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const_iterator data_it = data_.find(*it);
136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (data_it != data_.end()) {
137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return SelectionData(data_it->first, data_it->second);
138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return SelectionData();
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::vector< ::Atom> SelectionFormatMap::GetTypes() const {
145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::vector< ::Atom> atoms;
146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (const_iterator it = data_.begin(); it != data_.end(); ++it)
147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    atoms.push_back(it->first);
148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return atoms;
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochSelectionData::SelectionData()
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : type_(None),
15668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      atom_cache_(gfx::GetXDisplay(), kSelectionDataAtoms) {
157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochSelectionData::SelectionData(
160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ::Atom type,
161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const scoped_refptr<base::RefCountedMemory>& memory)
162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    : type_(type),
163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      memory_(memory),
16468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      atom_cache_(gfx::GetXDisplay(), kSelectionDataAtoms) {
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochSelectionData::SelectionData(const SelectionData& rhs)
168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    : type_(rhs.type_),
169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      memory_(rhs.memory_),
17068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      atom_cache_(gfx::GetXDisplay(), kSelectionDataAtoms) {
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochSelectionData::~SelectionData() {}
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochSelectionData& SelectionData::operator=(const SelectionData& rhs) {
176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  type_ = rhs.type_;
177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  memory_ = rhs.memory_;
178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(erg): In some future where we have to support multiple X Displays,
179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // the following will also need to deal with the display.
180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return *this;
181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool SelectionData::IsValid() const {
184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return type_ != None;
185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch::Atom SelectionData::GetType() const {
188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return type_;
189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst unsigned char* SelectionData::GetData() const {
1927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return memory_.get() ? memory_->front() : NULL;
193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochsize_t SelectionData::GetSize() const {
1967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return memory_.get() ? memory_->size() : 0;
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string SelectionData::GetText() const {
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (type_ == atom_cache_.GetAtom(kUtf8String) ||
201effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      type_ == atom_cache_.GetAtom(kText) ||
202effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      type_ == atom_cache_.GetAtom(kTextPlainUtf8)) {
203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return RefCountedMemoryToString(memory_);
204effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  } else if (type_ == atom_cache_.GetAtom(kString) ||
205effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch             type_ == atom_cache_.GetAtom(kTextPlain)) {
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string result;
207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::ConvertToUtf8AndNormalize(RefCountedMemoryToString(memory_),
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                    base::kCodepageLatin1,
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                    &result);
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return result;
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // BTW, I looked at COMPOUND_TEXT, and there's no way we're going to
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // support that. Yuck.
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    NOTREACHED();
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return std::string();
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 SelectionData::GetHtml() const {
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::string16 markup;
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (type_ == atom_cache_.GetAtom(Clipboard::kMimeTypeHTML)) {
223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const unsigned char* data = GetData();
224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    size_t size = GetSize();
225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If the data starts with 0xFEFF, i.e., Byte Order Mark, assume it is
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // UTF-16, otherwise assume UTF-8.
228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (size >= 2 &&
229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        reinterpret_cast<const uint16_t*>(data)[0] == 0xFEFF) {
230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      markup.assign(reinterpret_cast<const uint16_t*>(data) + 1,
231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                    (size / 2) - 1);
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else {
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::UTF8ToUTF16(reinterpret_cast<const char*>(data), size, &markup);
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If there is a terminating NULL, drop it.
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!markup.empty() && markup.at(markup.length() - 1) == '\0')
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      markup.resize(markup.length() - 1);
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return markup;
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    NOTREACHED();
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return markup;
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SelectionData::AssignTo(std::string* result) const {
248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  *result = RefCountedMemoryToString(memory_);
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SelectionData::AssignTo(base::string16* result) const {
252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  *result = RefCountedMemoryToString16(memory_);
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace ui
256