1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <array> 18 #include <cstdint> 19 20 #include <gtest/gtest.h> 21 22 #include "netdutils/Slice.h" 23 #include "netdutils/Status.h" 24 #include "netdutils/StatusOr.h" 25 26 namespace android { 27 namespace netdutils { 28 29 class SliceTest : public testing::Test { 30 protected: 31 std::array<char, 256> mRaw = {}; 32 }; 33 34 TEST_F(SliceTest, smoke) { 35 Slice s1 = makeSlice(mRaw); 36 Slice s2 = makeSlice(mRaw); 37 auto p = split(s1, 14); 38 s2 = p.first; // avoid warn-unused error 39 std::stringstream ss; 40 ss << Slice(); 41 EXPECT_EQ("Slice[base: 0x0, limit: 0x0, size: 0x0]", ss.str()); 42 constexpr size_t kBytes = 14; 43 EXPECT_EQ(s1.base(), take(s1, kBytes).base()); 44 EXPECT_EQ(kBytes, take(s1, kBytes).size()); 45 EXPECT_EQ(s1.base() + kBytes, drop(s1, kBytes).base()); 46 EXPECT_EQ(s1.size() - kBytes, drop(s1, kBytes).size()); 47 double a = 0; 48 double b = 0; 49 int c = 0; 50 EXPECT_EQ(sizeof(a), extract(s1, a)); 51 EXPECT_EQ(sizeof(a) + sizeof(b), extract(s1, a, b)); 52 EXPECT_EQ(sizeof(a) + sizeof(b) + sizeof(c), extract(s1, a, b, c)); 53 } 54 55 TEST_F(SliceTest, constructor) { 56 // Expect the following lines to compile 57 Slice s1 = makeSlice(mRaw); 58 Slice s2(s1); 59 Slice s3 = s2; 60 const Slice s4(s3); 61 const Slice s5 = s4; 62 s3 = s5; 63 Slice s6(mRaw.data(), mRaw.size()); 64 Slice s7(mRaw.data(), mRaw.data() + mRaw.size()); 65 struct { 66 int a; 67 double b; 68 float c; 69 } anon; 70 makeSlice(anon); 71 EXPECT_EQ(reinterpret_cast<uint8_t*>(mRaw.data()), s1.base()); 72 EXPECT_EQ(reinterpret_cast<uint8_t*>(mRaw.data()) + mRaw.size(), s1.limit()); 73 EXPECT_EQ(mRaw.size(), s1.size()); 74 EXPECT_FALSE(mRaw.empty()); 75 EXPECT_TRUE(Slice().empty()); 76 EXPECT_TRUE(Slice(nullptr, static_cast<size_t>(0)).empty()); 77 EXPECT_TRUE(Slice(nullptr, nullptr).empty()); 78 } 79 80 TEST_F(SliceTest, extract) { 81 struct A { 82 int a, b; 83 bool operator==(const A& other) const { return a == other.a && b == other.b; } 84 }; 85 struct B { 86 char str[12]; 87 bool b; 88 int i; 89 bool operator==(const B& other) const { 90 return b == other.b && i == other.i && 0 == strncmp(str, other.str, 12); 91 } 92 }; 93 94 A origA1 = {1, 2}; 95 A origA2 = {3, 4}; 96 B origB = {"hello world", true, 1234}; 97 98 // Populate buffer for extracting. 99 Slice buffer = makeSlice(mRaw); 100 copy(buffer, makeSlice(origA1)); 101 copy(drop(buffer, sizeof(origA1)), makeSlice(origB)); 102 copy(drop(buffer, sizeof(origA1) + sizeof(origB)), makeSlice(origA2)); 103 104 { 105 // Non-variadic extract 106 A a1{}; 107 size_t len = extract(buffer, a1); 108 EXPECT_EQ(sizeof(A), len); 109 EXPECT_EQ(origA1, a1); 110 } 111 112 { 113 // Variadic extract, 2 destinations 114 A a1{}; 115 B b{}; 116 size_t len = extract(buffer, a1, b); 117 EXPECT_EQ(sizeof(A) + sizeof(B), len); 118 EXPECT_EQ(origA1, a1); 119 EXPECT_EQ(origB, b); 120 } 121 122 { 123 // Variadic extract, 3 destinations 124 A a1{}, a2{}; 125 B b{}; 126 size_t len = extract(buffer, a1, b, a2); 127 EXPECT_EQ(2 * sizeof(A) + sizeof(B), len); 128 EXPECT_EQ(origA1, a1); 129 EXPECT_EQ(origB, b); 130 EXPECT_EQ(origA2, a2); 131 } 132 } 133 134 } // namespace netdutils 135 } // namespace android 136