1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // TODO(dcheng): For efficiency reasons, consider passing custom data around
6 // as a vector instead. It allows us to append a
7 // std::pair<base::string16, base::string16> and swap the deserialized values.
9 #include "ui/base/clipboard/custom_data_helper.h"
13 #include "base/pickle.h"
19 class SkippablePickle
: public Pickle
{
21 SkippablePickle(const void* data
, size_t data_len
);
22 bool SkipString16(PickleIterator
* iter
);
25 SkippablePickle::SkippablePickle(const void* data
, size_t data_len
)
26 : Pickle(reinterpret_cast<const char*>(data
), data_len
) {
29 bool SkippablePickle::SkipString16(PickleIterator
* iter
) {
33 if (!ReadLength(iter
, &len
))
35 return iter
->SkipBytes(len
* sizeof(base::char16
));
40 void ReadCustomDataTypes(const void* data
,
42 std::vector
<base::string16
>* types
) {
43 SkippablePickle
pickle(data
, data_length
);
44 PickleIterator
iter(pickle
);
47 if (!pickle
.ReadUInt64(&iter
, &size
))
50 // Keep track of the original elements in the types vector. On failure, we
51 // truncate the vector to the original size since we want to ignore corrupt
52 // custom data pickles.
53 uint64 original_size
= types
->size();
55 for (uint64 i
= 0; i
< size
; ++i
) {
56 types
->push_back(base::string16());
57 if (!pickle
.ReadString16(&iter
, &types
->back()) ||
58 !pickle
.SkipString16(&iter
)) {
59 types
->resize(original_size
);
65 void ReadCustomDataForType(const void* data
,
67 const base::string16
& type
,
68 base::string16
* result
) {
69 SkippablePickle
pickle(data
, data_length
);
70 PickleIterator
iter(pickle
);
73 if (!pickle
.ReadUInt64(&iter
, &size
))
76 for (uint64 i
= 0; i
< size
; ++i
) {
77 base::string16 deserialized_type
;
78 if (!pickle
.ReadString16(&iter
, &deserialized_type
))
80 if (deserialized_type
== type
) {
81 ignore_result(pickle
.ReadString16(&iter
, result
));
84 if (!pickle
.SkipString16(&iter
))
89 void ReadCustomDataIntoMap(const void* data
,
91 std::map
<base::string16
, base::string16
>* result
) {
92 Pickle
pickle(reinterpret_cast<const char*>(data
), data_length
);
93 PickleIterator
iter(pickle
);
96 if (!pickle
.ReadUInt64(&iter
, &size
))
99 for (uint64 i
= 0; i
< size
; ++i
) {
101 if (!pickle
.ReadString16(&iter
, &type
)) {
102 // Data is corrupt, return an empty map.
106 std::pair
<std::map
<base::string16
, base::string16
>::iterator
, bool>
107 insert_result
= result
->insert(std::make_pair(type
, base::string16()));
108 if (!pickle
.ReadString16(&iter
, &insert_result
.first
->second
)) {
109 // Data is corrupt, return an empty map.
116 void WriteCustomDataToPickle(
117 const std::map
<base::string16
, base::string16
>& data
,
119 pickle
->WriteUInt64(data
.size());
120 for (std::map
<base::string16
, base::string16
>::const_iterator it
=
124 pickle
->WriteString16(it
->first
);
125 pickle
->WriteString16(it
->second
);