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