1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file. 4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#ifndef MOJO_PUBLIC_BINDINGS_LIB_ARRAY_H_ 6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#define MOJO_PUBLIC_BINDINGS_LIB_ARRAY_H_ 7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <string.h> 9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <algorithm> 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <string> 12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <vector> 13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "mojo/public/bindings/lib/array_internal.h" 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace mojo { 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Provides read-only access to array data. 19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <typename T> 20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class Array { 21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) typedef internal::ArrayTraits<T, internal::TypeTraits<T>::kIsObject> Traits_; 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) typedef typename Traits_::DataType Data; 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) typedef typename Traits_::ConstRef ConstRef; 25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Array() : data_(NULL) { 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) template <typename U> 30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Array(const U& u, Buffer* buf = Buffer::current()) { 31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) *this = TypeConverter<Array<T>,U>::ConvertFrom(u, buf); 32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) template <typename U> 35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Array& operator=(const U& u) { 36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) *this = TypeConverter<Array<T>,U>::ConvertFrom(u, Buffer::current()); 37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return *this; 38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) template <typename U> 41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) operator U() const { 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return To<U>(); 43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) template <typename U> 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) U To() const { 47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return TypeConverter<Array<T>,U>::ConvertTo(*this); 48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool is_null() const { return !data_; } 51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) size_t size() const { return data_->size(); } 53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ConstRef at(size_t offset) const { 55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return Traits_::ToConstRef(data_->at(offset)); 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ConstRef operator[](size_t offset) const { return at(offset); } 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Provides a way to initialize an array element-by-element. 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) class Builder { 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) typedef typename Array<T>::Data Data; 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) typedef typename Array<T>::Traits_ Traits_; 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) typedef typename Traits_::Ref Ref; 65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) explicit Builder(size_t num_elements, Buffer* buf = mojo::Buffer::current()) 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : data_(Data::New(num_elements, buf)) { 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) size_t size() const { return data_->size(); } 71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Ref at(size_t offset) { 73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return Traits_::ToRef(data_->at(offset)); 74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Ref operator[](size_t offset) { return at(offset); } 76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Array<T> Finish() { 78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Data* data = NULL; 79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::swap(data, data_); 80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return internal::Wrap(data); 81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private: 84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Data* data_; 85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) MOJO_DISALLOW_COPY_AND_ASSIGN(Builder); 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) }; 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) protected: 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) friend class internal::WrapperHelper<Array<T> >; 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) struct Wrap {}; 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Array(Wrap, const Data* data) : data_(data) {} 93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const Data* data_; 95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// UTF-8 encoded 98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)typedef Array<char> String; 99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <> 101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class TypeConverter<String, std::string> { 102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static String ConvertFrom(const std::string& input, Buffer* buf); 104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static std::string ConvertTo(const String& input); 105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <size_t N> 108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class TypeConverter<String, char[N]> { 109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static String ConvertFrom(const char input[N], Buffer* buf) { 111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) String::Builder result(N - 1, buf); 112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) memcpy(&result[0], input, N - 1); 113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return result.Finish(); 114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Appease MSVC. 118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <size_t N> 119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class TypeConverter<String, const char[N]> { 120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static String ConvertFrom(const char input[N], Buffer* buf) { 122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return TypeConverter<String, char[N]>::ConvertFrom(input, buf); 123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <> 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class TypeConverter<String, const char*> { 128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static String ConvertFrom(const char* input, Buffer* buf); 130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // NOTE: |ConvertTo| explicitly not implemented since String is not null 131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // terminated (and may have embedded null bytes). 132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <typename T, typename E> 135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class TypeConverter<Array<T>, std::vector<E> > { 136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static Array<T> ConvertFrom(const std::vector<E>& input, Buffer* buf) { 138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) typename Array<T>::Builder result(input.size(), buf); 139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (size_t i = 0; i < input.size(); ++i) 140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) result[i] = TypeConverter<T, E>::ConvertFrom(input[i], buf); 141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return result.Finish(); 142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static std::vector<E> ConvertTo(const Array<T>& input) { 144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::vector<E> result; 145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!input.is_null()) { 146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) result.resize(input.size()); 147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (size_t i = 0; i < input.size(); ++i) 148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) result[i] = TypeConverter<T, E>::ConvertTo(input[i]); 149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return result; 151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace mojo 155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif // MOJO_PUBLIC_BINDINGS_LIB_ARRAY_H_ 157