Chromium Code Reviews| Index: ui/base/clipboard/custom_data_helper.cc |
| diff --git a/ui/base/clipboard/custom_data_helper.cc b/ui/base/clipboard/custom_data_helper.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..72142b518855cf56bd01665241f481536f09b3c8 |
| --- /dev/null |
| +++ b/ui/base/clipboard/custom_data_helper.cc |
| @@ -0,0 +1,127 @@ |
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| +// |
| +// TODO(dcheng): For efficiency reasons, consider passing custom data around |
| +// as a vector instead. It allows us to append a |
| +// std::pair<string16, string16> and swap the deserialized values in. |
| + |
| +#include "ui/base/clipboard/custom_data_helper.h" |
| + |
| +#include <utility> |
| + |
| +#include "base/pickle.h" |
| + |
| +namespace ui { |
| + |
| +namespace { |
| + |
| +class SkippablePickle : public Pickle { |
| + public: |
| + SkippablePickle(const void* data, size_t data_len); |
| + bool SkipString16(void** iter); |
| +}; |
| + |
| +SkippablePickle::SkippablePickle(const void* data, size_t data_len) |
| + : Pickle(reinterpret_cast<const char*>(data), data_len) { |
| +} |
| + |
| +bool SkippablePickle::SkipString16(void** iter) { |
| + DCHECK(iter); |
| + |
| + int len; |
| + if (!ReadLength(iter, &len)) |
| + return false; |
| + if (!IteratorHasRoomFor(*iter, len * sizeof(char16))) |
| + return false; |
| + |
| + UpdateIter(iter, len * sizeof(char16)); |
| + return true; |
| +} |
| + |
| +} // namespace |
| + |
| +void ReadCustomDataTypes(const void* data, |
| + size_t data_length, |
| + std::vector<string16>* types) { |
| + SkippablePickle pickle(data, data_length); |
| + void* iter = NULL; |
| + |
| + size_t size = 0; |
| + if (!pickle.ReadSize(&iter, &size)) |
| + return; |
| + |
| + // Keep track of the original elements in the types vector. On failure, we |
| + // truncate the vector to the original size since we want to ignore corrupt |
| + // custom data pickles. |
| + size_t original_size = types->size(); |
| + |
| + for (size_t i = 0; i < size; ++i) { |
| + types->push_back(string16()); |
| + if (!pickle.ReadString16(&iter, &types->back()) || |
| + !pickle.SkipString16(&iter)) { |
| + types->resize(original_size); |
| + return; |
| + } |
| + } |
| +} |
| + |
| +void ReadCustomDataForType(const void* data, |
| + size_t data_length, |
| + const string16& type, |
| + string16* result) { |
| + SkippablePickle pickle(data, data_length); |
| + void* iter = NULL; |
| + |
| + size_t size = 0; |
| + if (!pickle.ReadSize(&iter, &size)) |
| + return; |
| + |
| + for (size_t i = 0; i < size; ++i) { |
| + string16 deserialized_type; |
| + if (!pickle.ReadString16(&iter, &deserialized_type)) |
| + return; |
| + if (deserialized_type == type) { |
| + pickle.ReadString16(&iter, result); |
| + return; |
| + } |
| + if (!pickle.SkipString16(&iter)) |
| + return; |
| + } |
| +} |
| + |
| +void ReadCustomDataIntoMap(const void* data, |
| + size_t data_length, |
| + std::map<string16, string16>* result) { |
| + Pickle pickle(reinterpret_cast<const char*>(data), data_length); |
| + void* iter = NULL; |
| + |
| + size_t size = 0; |
| + if (!pickle.ReadSize(&iter, &size)) |
| + return; |
| + |
| + for (size_t i = 0; i < size; ++i) { |
| + string16 type; |
| + string16 data; |
|
tony
2011/12/05 18:20:16
Nit: string16 data shadows the function arg data.
dcheng
2011/12/05 18:34:10
Done. Not needed any more since we saved a copy be
|
| + if (!pickle.ReadString16(&iter, &type) || |
| + !pickle.ReadString16(&iter, &data)) { |
| + // Data is corrupt, return an empty map. |
| + result->clear(); |
| + return; |
| + } |
| + result->insert(std::make_pair(type, data)); |
|
tony
2011/12/05 18:20:16
Nit: I think we can save a copy of |data| by readi
dcheng
2011/12/05 18:34:10
Done.
|
| + } |
| +} |
| + |
| +void WriteCustomDataToPickle(const std::map<string16, string16>& data, |
| + Pickle* pickle) { |
| + pickle->WriteSize(data.size()); |
| + for (std::map<string16, string16>::const_iterator it = data.begin(); |
| + it != data.end(); |
| + ++it) { |
| + pickle->WriteString16(it->first); |
| + pickle->WriteString16(it->second); |
| + } |
| +} |
| + |
| +} // namespace ui |