Home | History | Annotate | Download | only in bindings
      1 // Copyright 2014 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_CPP_BINDINGS_STRING_H_
      6 #define MOJO_PUBLIC_CPP_BINDINGS_STRING_H_
      7 
      8 #include <string>
      9 
     10 #include "mojo/public/cpp/bindings/lib/array_internal.h"
     11 #include "mojo/public/cpp/bindings/type_converter.h"
     12 #include "mojo/public/cpp/environment/logging.h"
     13 
     14 namespace mojo {
     15 
     16 class String {
     17  public:
     18   typedef internal::String_Data Data_;
     19 
     20   String() : is_null_(true) {}
     21   String(const std::string& str) : value_(str), is_null_(false) {}
     22   String(const char* chars) : is_null_(!chars) {
     23     if (chars)
     24       value_ = chars;
     25   }
     26   String(const char* chars, size_t num_chars)
     27       : value_(chars, num_chars),
     28         is_null_(false) {
     29   }
     30   template <size_t N>
     31   String(const char chars[N]) : value_(chars, N-1), is_null_(false) {}
     32 
     33   template <typename U>
     34   static String From(const U& other) {
     35     return TypeConverter<String, U>::Convert(other);
     36   }
     37 
     38   template <typename U>
     39   U To() const {
     40     return TypeConverter<U, String>::Convert(*this);
     41   }
     42 
     43   String& operator=(const std::string& str) {
     44     value_ = str;
     45     is_null_ = false;
     46     return *this;
     47   }
     48   String& operator=(const char* chars) {
     49     is_null_ = !chars;
     50     if (chars) {
     51       value_ = chars;
     52     } else {
     53       value_.clear();
     54     }
     55     return *this;
     56   }
     57 
     58   void reset() {
     59     value_.clear();
     60     is_null_ = true;
     61   }
     62 
     63   bool is_null() const { return is_null_; }
     64 
     65   size_t size() const { return value_.size(); }
     66 
     67   const char* data() const { return value_.data(); }
     68 
     69   const char& at(size_t offset) const { return value_.at(offset); }
     70   const char& operator[](size_t offset) const { return value_[offset]; }
     71 
     72   const std::string& get() const { return value_; }
     73   operator const std::string&() const { return value_; }
     74 
     75   void Swap(String* other) {
     76     std::swap(is_null_, other->is_null_);
     77     value_.swap(other->value_);
     78   }
     79 
     80   void Swap(std::string* other) {
     81     is_null_ = false;
     82     value_.swap(*other);
     83   }
     84 
     85  private:
     86   typedef std::string String::*Testable;
     87 
     88  public:
     89   operator Testable() const { return is_null_ ? 0 : &String::value_; }
     90 
     91  private:
     92   std::string value_;
     93   bool is_null_;
     94 };
     95 
     96 inline bool operator==(const String& a, const String& b) {
     97   return a.is_null() == b.is_null() && a.get() == b.get();
     98 }
     99 inline bool operator==(const char* a, const String& b) {
    100   return !b.is_null() && a == b.get();
    101 }
    102 inline bool operator==(const String& a, const char* b) {
    103   return !a.is_null() && a.get() == b;
    104 }
    105 inline bool operator!=(const String& a, const String& b) { return !(a == b); }
    106 inline bool operator!=(const char* a, const String& b) { return !(a == b); }
    107 inline bool operator!=(const String& a, const char* b) { return !(a == b); }
    108 
    109 inline std::ostream& operator<<(std::ostream& out, const String& s) {
    110   return out << s.get();
    111 }
    112 
    113 // TODO(darin): Add similar variants of operator<,<=,>,>=
    114 
    115 template <>
    116 struct TypeConverter<String, std::string> {
    117   static String Convert(const std::string& input) { return String(input); }
    118 };
    119 
    120 template <>
    121 struct TypeConverter<std::string, String> {
    122   static std::string Convert(const String& input) { return input; }
    123 };
    124 
    125 template <size_t N>
    126 struct TypeConverter<String, char[N]> {
    127   static String Convert(const char input[N]) {
    128     MOJO_DCHECK(input);
    129     return String(input, N-1);
    130   }
    131 };
    132 
    133 // Appease MSVC.
    134 template <size_t N>
    135 struct TypeConverter<String, const char[N]> {
    136   static String Convert(const char input[N]) {
    137     MOJO_DCHECK(input);
    138     return String(input, N-1);
    139   }
    140 };
    141 
    142 template <>
    143 struct TypeConverter<String, const char*> {
    144   // |input| may be null, in which case a null String will be returned.
    145   static String Convert(const char* input) { return String(input); }
    146 };
    147 
    148 }  // namespace mojo
    149 
    150 #endif  // MOJO_PUBLIC_CPP_BINDINGS_STRING_H_
    151