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
TEST_F(SliceTest,smoke)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
TEST_F(SliceTest,constructor)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
TEST_F(SliceTest,extract)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