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