Add hidl_vec iterator and hidl_string ==

Add bidirectional iterator for hidl_vec
Add operator== and operator!= for hidl_string to hidl_string
comparision.

Test:  Added unit tests to libhidl_test
Change-Id: I908bc71fae4016f335e2342f28b351f63f22fa66
diff --git a/base/include/hidl/HidlSupport.h b/base/include/hidl/HidlSupport.h
index 0da0e37..c604f56 100644
--- a/base/include/hidl/HidlSupport.h
+++ b/base/include/hidl/HidlSupport.h
@@ -20,6 +20,7 @@
 #include <algorithm>
 #include <dirent.h>
 #include <dlfcn.h>
+#include <iterator>
 #include <cutils/properties.h>
 #include <functional>
 #include <hidl/Status.h>
@@ -158,6 +159,14 @@
     void moveFrom(hidl_string &&);
 };
 
+inline bool operator==(const hidl_string &hs1, const hidl_string &hs2) {
+    return strcmp(hs1.c_str(), hs2.c_str()) == 0;
+}
+
+inline bool operator!=(const hidl_string &hs1, const hidl_string &hs2) {
+    return !(hs1 == hs2);
+}
+
 inline bool operator==(const hidl_string &hs, const char *s) {
     return strcmp(hs.c_str(), s) == 0;
 }
@@ -319,6 +328,27 @@
 
     // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
     static const size_t kOffsetOfBuffer;
+
+    // Define std interator interface for walking the array contents
+    // TODO:  it might be nice to implement a full featured random access iterator...
+    class iterator : public std::iterator<std::bidirectional_iterator_tag, T>
+    {
+    public:
+        iterator(T* ptr) : mPtr(ptr) { }
+        iterator operator++()    { iterator i = *this; mPtr++; return i; }
+        iterator operator++(int) { mPtr++; return *this; }
+        iterator operator--()    { iterator i = *this; mPtr--; return i; }
+        iterator operator--(int) { mPtr--; return *this; }
+        T& operator*()  { return *mPtr; }
+        T* operator->() { return mPtr; }
+        bool operator==(const iterator& rhs) const { return mPtr == rhs.mPtr; }
+        bool operator!=(const iterator& rhs) const { return mPtr != rhs.mPtr; }
+    private:
+        T* mPtr;
+    };
+    iterator begin() { return data(); }
+    iterator end() { return data()+mSize; }
+
 private:
     details::hidl_pointer<T> mBuffer;
     uint32_t mSize;
diff --git a/test_main.cpp b/test_main.cpp
index f964ce5..276b3a4 100644
--- a/test_main.cpp
+++ b/test_main.cpp
@@ -67,12 +67,36 @@
     EXPECT_STREQ(s, "myDString");
     s.clear(); // should not affect myCString
     EXPECT_STREQ(myCString, "myDString");
+
     // casts
     s = "great";
     std::string myString = s;
     const char *anotherCString = s;
     EXPECT_EQ(myString, "great");
     EXPECT_STREQ(anotherCString, "great");
+
+    // Comparisons
+    const char * cstr1 = "abc";
+    std::string string1(cstr1);
+    hidl_string hs1(cstr1);
+    const char * cstrE = "abc";
+    std::string stringE(cstrE);
+    hidl_string hsE(cstrE);
+    const char * cstrNE = "ABC";
+    std::string stringNE(cstrNE);
+    hidl_string hsNE(cstrNE);
+    EXPECT_TRUE(hs1  == hsE);
+    EXPECT_FALSE(hs1 != hsE);
+    EXPECT_TRUE(hs1  != hsNE);
+    EXPECT_FALSE(hs1 == hsNE);
+    EXPECT_TRUE(hs1  == cstrE);
+    EXPECT_FALSE(hs1 != cstrE);
+    EXPECT_TRUE(hs1  != cstrNE);
+    EXPECT_FALSE(hs1 == cstrNE);
+    EXPECT_TRUE(hs1  == stringE);
+    EXPECT_FALSE(hs1 != stringE);
+    EXPECT_TRUE(hs1  != stringNE);
+    EXPECT_FALSE(hs1 == stringNE);
 }
 
 TEST_F(LibHidlTest, VecTest) {
@@ -93,6 +117,19 @@
     hidl_vec<int32_t> v3 = {5, 6, 7}; // initializer_list
     EXPECT_EQ(v3.size(), 3ul);
     EXPECT_ARRAYEQ(v3, array, v3.size());
+
+    auto iter = hv1.begin();    // iterator begin()
+    EXPECT_EQ(*iter, 5);
+    iter++;                     // post increment
+    EXPECT_EQ(*iter, 6);
+    ++iter;                     // pre increment
+    EXPECT_EQ(*iter, 7);
+
+    int32_t sum = 0;            // range based for loop interoperability
+    for (auto &&i: hv1) {
+        sum += i;
+    }
+    EXPECT_EQ(sum, 5+6+7);
 }
 
 TEST_F(LibHidlTest, ArrayTest) {