19205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko// Copyright 2014 The Chromium OS Authors. All rights reserved.
29205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko// Use of this source code is governed by a BSD-style license that can be
39205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko// found in the LICENSE file.
49205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko
59205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko#include <string>
69205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko
79ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/any.h>
89205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko#include <gtest/gtest.h>
99205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko
109ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenkousing brillo::internal_details::Buffer;
114d8501c1f9689c833d38c9087df28b971a6ebe42Alex Vakulenkousing brillo::GetTypeTag;
129205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko
139205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex VakulenkoTEST(Buffer, Empty) {
149205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  Buffer buffer;
159205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_TRUE(buffer.IsEmpty());
169205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_EQ(Buffer::kExternal, buffer.storage_);
179205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_EQ(nullptr, buffer.GetDataPtr());
189205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko}
199205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko
209205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex VakulenkoTEST(Buffer, Store_Int) {
219205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  Buffer buffer;
229205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  buffer.Assign(2);
239205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_FALSE(buffer.IsEmpty());
249205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_EQ(Buffer::kContained, buffer.storage_);
254d8501c1f9689c833d38c9087df28b971a6ebe42Alex Vakulenko  EXPECT_STREQ(GetTypeTag<int>(), buffer.GetDataPtr()->GetTypeTag());
269205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko}
279205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko
289205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex VakulenkoTEST(Buffer, Store_Double) {
299205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  Buffer buffer;
309205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  buffer.Assign(2.3);
319205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_FALSE(buffer.IsEmpty());
329205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_EQ(Buffer::kContained, buffer.storage_);
334d8501c1f9689c833d38c9087df28b971a6ebe42Alex Vakulenko  EXPECT_STREQ(GetTypeTag<double>(), buffer.GetDataPtr()->GetTypeTag());
349205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko}
359205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko
369205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex VakulenkoTEST(Buffer, Store_Pointers) {
379205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  Buffer buffer;
389205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  // nullptr
399205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  buffer.Assign(nullptr);
409205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_FALSE(buffer.IsEmpty());
419205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_EQ(Buffer::kContained, buffer.storage_);
424d8501c1f9689c833d38c9087df28b971a6ebe42Alex Vakulenko  EXPECT_STREQ(GetTypeTag<std::nullptr_t>(),
434d8501c1f9689c833d38c9087df28b971a6ebe42Alex Vakulenko               buffer.GetDataPtr()->GetTypeTag());
449205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko
459205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  // char *
469205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  buffer.Assign("abcd");
479205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_FALSE(buffer.IsEmpty());
489205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_EQ(Buffer::kContained, buffer.storage_);
494d8501c1f9689c833d38c9087df28b971a6ebe42Alex Vakulenko  EXPECT_STREQ(GetTypeTag<const char*>(), buffer.GetDataPtr()->GetTypeTag());
509205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko
519205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  // pointer to non-trivial object
529205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  class NonTrivial {
539205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko   public:
549205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko    virtual ~NonTrivial() {}
559205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  } non_trivial;
569205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  buffer.Assign(&non_trivial);
579205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_FALSE(buffer.IsEmpty());
589205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_EQ(Buffer::kContained, buffer.storage_);
594d8501c1f9689c833d38c9087df28b971a6ebe42Alex Vakulenko  EXPECT_STREQ(GetTypeTag<NonTrivial*>(), buffer.GetDataPtr()->GetTypeTag());
609205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko}
619205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko
629205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex VakulenkoTEST(Buffer, Store_NonTrivialObjects) {
639205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  class NonTrivial {
649205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko   public:
659205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko    virtual ~NonTrivial() {}
669205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  } non_trivial;
679205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  Buffer buffer;
689205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  buffer.Assign(non_trivial);
699205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_FALSE(buffer.IsEmpty());
709205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_EQ(Buffer::kExternal, buffer.storage_);
714d8501c1f9689c833d38c9087df28b971a6ebe42Alex Vakulenko  EXPECT_STREQ(GetTypeTag<NonTrivial>(), buffer.GetDataPtr()->GetTypeTag());
729205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko}
739205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko
749205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex VakulenkoTEST(Buffer, Store_Objects) {
759205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  Buffer buffer;
769205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko
779205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  struct Small {
789205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko    double d;
799205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  } small = {};
809205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  buffer.Assign(small);
819205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_FALSE(buffer.IsEmpty());
829205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_EQ(Buffer::kContained, buffer.storage_);
834d8501c1f9689c833d38c9087df28b971a6ebe42Alex Vakulenko  EXPECT_STREQ(GetTypeTag<Small>(), buffer.GetDataPtr()->GetTypeTag());
849205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko
859205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  struct Large {
86d4d2d739c3b22e686881df519fc40e6f331d5eaeAlex Vakulenko    char c[20];
879205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  } large = {};
889205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  buffer.Assign(large);
899205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_FALSE(buffer.IsEmpty());
909205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_EQ(Buffer::kExternal, buffer.storage_);
914d8501c1f9689c833d38c9087df28b971a6ebe42Alex Vakulenko  EXPECT_STREQ(GetTypeTag<Large>(), buffer.GetDataPtr()->GetTypeTag());
929205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko}
939205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko
949205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex VakulenkoTEST(Buffer, Copy) {
959205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  Buffer buffer1;
969205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  Buffer buffer2;
979205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko
989205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  buffer1.Assign(30);
999205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  buffer1.CopyTo(&buffer2);
1009205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_FALSE(buffer1.IsEmpty());
1019205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_FALSE(buffer2.IsEmpty());
1024d8501c1f9689c833d38c9087df28b971a6ebe42Alex Vakulenko  EXPECT_STREQ(GetTypeTag<int>(), buffer1.GetDataPtr()->GetTypeTag());
1034d8501c1f9689c833d38c9087df28b971a6ebe42Alex Vakulenko  EXPECT_STREQ(GetTypeTag<int>(), buffer2.GetDataPtr()->GetTypeTag());
1049205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_EQ(30, buffer1.GetData<int>());
1059205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_EQ(30, buffer2.GetData<int>());
1069205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko
1079205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  buffer1.Assign(std::string("abc"));
1089205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  buffer1.CopyTo(&buffer2);
1099205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_FALSE(buffer1.IsEmpty());
1109205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_FALSE(buffer2.IsEmpty());
1114d8501c1f9689c833d38c9087df28b971a6ebe42Alex Vakulenko  EXPECT_STREQ(GetTypeTag<std::string>(), buffer1.GetDataPtr()->GetTypeTag());
1124d8501c1f9689c833d38c9087df28b971a6ebe42Alex Vakulenko  EXPECT_STREQ(GetTypeTag<std::string>(), buffer2.GetDataPtr()->GetTypeTag());
1139205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_EQ("abc", buffer1.GetData<std::string>());
1149205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_EQ("abc", buffer2.GetData<std::string>());
1159205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko}
1169205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko
1179205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex VakulenkoTEST(Buffer, Move) {
1189205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  // Move operations essentially leave the source object in a state that is
1199205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  // guaranteed to be safe for reuse or destruction. There is no other explicit
1209205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  // guarantees on the exact state of the source after move (e.g. that the
1219205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  // source Any will be Empty after the move is complete).
1229205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  Buffer buffer1;
1239205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  Buffer buffer2;
1249205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko
1259205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  buffer1.Assign(30);
1269205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  buffer1.MoveTo(&buffer2);
1279205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  // Contained types aren't flushed, so the source Any doesn't become empty.
1289205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  // The contained value is just moved, but for scalars this just copies
1299205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  // the data and any retains the actual type.
1309205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_FALSE(buffer1.IsEmpty());
1319205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_FALSE(buffer2.IsEmpty());
1324d8501c1f9689c833d38c9087df28b971a6ebe42Alex Vakulenko  EXPECT_STREQ(GetTypeTag<int>(), buffer2.GetDataPtr()->GetTypeTag());
1339205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_EQ(30, buffer2.GetData<int>());
1349205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko
1359205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  buffer1.Assign(std::string("abc"));
1369205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  buffer1.MoveTo(&buffer2);
1379205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  // External types are moved by just moving the pointer value from src to dest.
1389205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  // This will make the source object effectively "Empty".
1399205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_TRUE(buffer1.IsEmpty());
1409205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_FALSE(buffer2.IsEmpty());
1414d8501c1f9689c833d38c9087df28b971a6ebe42Alex Vakulenko  EXPECT_STREQ(GetTypeTag<std::string>(), buffer2.GetDataPtr()->GetTypeTag());
1429205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko  EXPECT_EQ("abc", buffer2.GetData<std::string>());
1439205c772a4a34ce16c7cfd9caee0d0c9b43bbee1Alex Vakulenko}
144