/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "netdutils/Slice.h" #include "netdutils/Status.h" #include "netdutils/StatusOr.h" namespace android { namespace netdutils { class SliceTest : public testing::Test { protected: std::array mRaw = {}; }; TEST_F(SliceTest, smoke) { Slice s1 = makeSlice(mRaw); Slice s2 = makeSlice(mRaw); auto p = split(s1, 14); s2 = p.first; // avoid warn-unused error std::stringstream ss; ss << Slice(); EXPECT_EQ("Slice[base: 0x0, limit: 0x0, size: 0x0]", ss.str()); constexpr size_t kBytes = 14; EXPECT_EQ(s1.base(), take(s1, kBytes).base()); EXPECT_EQ(kBytes, take(s1, kBytes).size()); EXPECT_EQ(s1.base() + kBytes, drop(s1, kBytes).base()); EXPECT_EQ(s1.size() - kBytes, drop(s1, kBytes).size()); double a = 0; double b = 0; int c = 0; EXPECT_EQ(sizeof(a), extract(s1, a)); EXPECT_EQ(sizeof(a) + sizeof(b), extract(s1, a, b)); EXPECT_EQ(sizeof(a) + sizeof(b) + sizeof(c), extract(s1, a, b, c)); } TEST_F(SliceTest, constructor) { // Expect the following lines to compile Slice s1 = makeSlice(mRaw); Slice s2(s1); Slice s3 = s2; const Slice s4(s3); const Slice s5 = s4; s3 = s5; Slice s6(mRaw.data(), mRaw.size()); Slice s7(mRaw.data(), mRaw.data() + mRaw.size()); struct { int a; double b; float c; } anon; makeSlice(anon); EXPECT_EQ(reinterpret_cast(mRaw.data()), s1.base()); EXPECT_EQ(reinterpret_cast(mRaw.data()) + mRaw.size(), s1.limit()); EXPECT_EQ(mRaw.size(), s1.size()); EXPECT_FALSE(mRaw.empty()); EXPECT_TRUE(Slice().empty()); EXPECT_TRUE(Slice(nullptr, static_cast(0)).empty()); EXPECT_TRUE(Slice(nullptr, nullptr).empty()); } TEST_F(SliceTest, extract) { struct A { int a, b; bool operator==(const A& other) const { return a == other.a && b == other.b; } }; struct B { char str[12]; bool b; int i; bool operator==(const B& other) const { return b == other.b && i == other.i && 0 == strncmp(str, other.str, 12); } }; A origA1 = {1, 2}; A origA2 = {3, 4}; B origB = {"hello world", true, 1234}; // Populate buffer for extracting. Slice buffer = makeSlice(mRaw); copy(buffer, makeSlice(origA1)); copy(drop(buffer, sizeof(origA1)), makeSlice(origB)); copy(drop(buffer, sizeof(origA1) + sizeof(origB)), makeSlice(origA2)); { // Non-variadic extract A a1{}; size_t len = extract(buffer, a1); EXPECT_EQ(sizeof(A), len); EXPECT_EQ(origA1, a1); } { // Variadic extract, 2 destinations A a1{}; B b{}; size_t len = extract(buffer, a1, b); EXPECT_EQ(sizeof(A) + sizeof(B), len); EXPECT_EQ(origA1, a1); EXPECT_EQ(origB, b); } { // Variadic extract, 3 destinations A a1{}, a2{}; B b{}; size_t len = extract(buffer, a1, b, a2); EXPECT_EQ(2 * sizeof(A) + sizeof(B), len); EXPECT_EQ(origA1, a1); EXPECT_EQ(origB, b); EXPECT_EQ(origA2, a2); } } } // namespace netdutils } // namespace android