1*b9df5ad1SAndroid Build Coastguard Worker /*
2*b9df5ad1SAndroid Build Coastguard Worker * Copyright 2020 The Android Open Source Project
3*b9df5ad1SAndroid Build Coastguard Worker *
4*b9df5ad1SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*b9df5ad1SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*b9df5ad1SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*b9df5ad1SAndroid Build Coastguard Worker *
8*b9df5ad1SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*b9df5ad1SAndroid Build Coastguard Worker *
10*b9df5ad1SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*b9df5ad1SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*b9df5ad1SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*b9df5ad1SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*b9df5ad1SAndroid Build Coastguard Worker * limitations under the License.
15*b9df5ad1SAndroid Build Coastguard Worker */
16*b9df5ad1SAndroid Build Coastguard Worker
17*b9df5ad1SAndroid Build Coastguard Worker #define METADATA_TESTING
18*b9df5ad1SAndroid Build Coastguard Worker
19*b9df5ad1SAndroid Build Coastguard Worker #include <audio_utils/Metadata.h>
20*b9df5ad1SAndroid Build Coastguard Worker #include <gtest/gtest.h>
21*b9df5ad1SAndroid Build Coastguard Worker #include <stdio.h>
22*b9df5ad1SAndroid Build Coastguard Worker
23*b9df5ad1SAndroid Build Coastguard Worker #include <error.h>
24*b9df5ad1SAndroid Build Coastguard Worker #include <iostream>
25*b9df5ad1SAndroid Build Coastguard Worker
26*b9df5ad1SAndroid Build Coastguard Worker using namespace android::audio_utils::metadata;
27*b9df5ad1SAndroid Build Coastguard Worker
28*b9df5ad1SAndroid Build Coastguard Worker // Preferred: Key in header - a constexpr which is created by the compiler.
29*b9df5ad1SAndroid Build Coastguard Worker inline constexpr CKey<std::string> ITS_NAME_IS("its_name_is");
30*b9df5ad1SAndroid Build Coastguard Worker
31*b9df5ad1SAndroid Build Coastguard Worker // Not preferred: Key which is created at run-time.
32*b9df5ad1SAndroid Build Coastguard Worker inline const Key<std::string> MY_NAME_IS("my_name_is");
33*b9df5ad1SAndroid Build Coastguard Worker
34*b9df5ad1SAndroid Build Coastguard Worker // The Metadata table
35*b9df5ad1SAndroid Build Coastguard Worker inline constexpr CKey<Data> TABLE("table");
36*b9df5ad1SAndroid Build Coastguard Worker
37*b9df5ad1SAndroid Build Coastguard Worker #ifdef METADATA_TESTING
38*b9df5ad1SAndroid Build Coastguard Worker
39*b9df5ad1SAndroid Build Coastguard Worker // Validate recursive typing on "Datum".
40*b9df5ad1SAndroid Build Coastguard Worker inline constexpr CKey<std::vector<Datum>> VECTOR("vector");
41*b9df5ad1SAndroid Build Coastguard Worker inline constexpr CKey<std::pair<Datum, Datum>> PAIR("pair");
42*b9df5ad1SAndroid Build Coastguard Worker
43*b9df5ad1SAndroid Build Coastguard Worker // Validate that we move instead of copy.
44*b9df5ad1SAndroid Build Coastguard Worker inline constexpr CKey<MoveCount> MOVE_COUNT("MoveCount");
45*b9df5ad1SAndroid Build Coastguard Worker
46*b9df5ad1SAndroid Build Coastguard Worker // Validate recursive container support.
47*b9df5ad1SAndroid Build Coastguard Worker inline constexpr CKey<std::vector<std::vector<std::pair<std::string, short>>>> FUNKY("funky");
48*b9df5ad1SAndroid Build Coastguard Worker
49*b9df5ad1SAndroid Build Coastguard Worker // Validate structured binding parceling.
50*b9df5ad1SAndroid Build Coastguard Worker inline constexpr CKey<Arbitrary> ARBITRARY("arbitrary");
51*b9df5ad1SAndroid Build Coastguard Worker #endif
52*b9df5ad1SAndroid Build Coastguard Worker
toString(const ByteString & bs)53*b9df5ad1SAndroid Build Coastguard Worker std::string toString(const ByteString &bs) {
54*b9df5ad1SAndroid Build Coastguard Worker std::stringstream ss;
55*b9df5ad1SAndroid Build Coastguard Worker ss << "{\n" << std::hex;
56*b9df5ad1SAndroid Build Coastguard Worker if (bs.size() > 0) {
57*b9df5ad1SAndroid Build Coastguard Worker for (size_t i = 0; ; ++i) {
58*b9df5ad1SAndroid Build Coastguard Worker if ((i & 7) == 0) {
59*b9df5ad1SAndroid Build Coastguard Worker ss << " ";
60*b9df5ad1SAndroid Build Coastguard Worker }
61*b9df5ad1SAndroid Build Coastguard Worker ss << "0x" << std::setfill('0') << std::setw(2) << (unsigned)bs[i];
62*b9df5ad1SAndroid Build Coastguard Worker if (i == bs.size() - 1) {
63*b9df5ad1SAndroid Build Coastguard Worker break;
64*b9df5ad1SAndroid Build Coastguard Worker } else if ((i & 7) == 7) {
65*b9df5ad1SAndroid Build Coastguard Worker ss << ",\n";
66*b9df5ad1SAndroid Build Coastguard Worker } else {
67*b9df5ad1SAndroid Build Coastguard Worker ss << ", ";
68*b9df5ad1SAndroid Build Coastguard Worker }
69*b9df5ad1SAndroid Build Coastguard Worker }
70*b9df5ad1SAndroid Build Coastguard Worker }
71*b9df5ad1SAndroid Build Coastguard Worker ss << "\n}\n";
72*b9df5ad1SAndroid Build Coastguard Worker return ss.str();
73*b9df5ad1SAndroid Build Coastguard Worker }
74*b9df5ad1SAndroid Build Coastguard Worker
TEST(metadata_tests,basic_datum)75*b9df5ad1SAndroid Build Coastguard Worker TEST(metadata_tests, basic_datum) {
76*b9df5ad1SAndroid Build Coastguard Worker Datum d;
77*b9df5ad1SAndroid Build Coastguard Worker d = "abc";
78*b9df5ad1SAndroid Build Coastguard Worker //ASSERT_EQ("abc", std::any_cast<const char *>(d));
79*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ("abc", std::any_cast<std::string>(d));
80*b9df5ad1SAndroid Build Coastguard Worker //d = std::vector<int>();
81*b9df5ad1SAndroid Build Coastguard Worker
82*b9df5ad1SAndroid Build Coastguard Worker Datum lore((int32_t) 10);
83*b9df5ad1SAndroid Build Coastguard Worker d = lore;
84*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(10, std::any_cast<int32_t>(d));
85*b9df5ad1SAndroid Build Coastguard Worker
86*b9df5ad1SAndroid Build Coastguard Worker // TODO: should we enable Datum to copy from std::any if the types
87*b9df5ad1SAndroid Build Coastguard Worker // are correct? The problem is how to signal failure.
88*b9df5ad1SAndroid Build Coastguard Worker std::any arg = (int)1;
89*b9df5ad1SAndroid Build Coastguard Worker // Datum invalid = arg; // this doesn't work.
90*b9df5ad1SAndroid Build Coastguard Worker
91*b9df5ad1SAndroid Build Coastguard Worker struct dummy {
92*b9df5ad1SAndroid Build Coastguard Worker int value = 0;
93*b9df5ad1SAndroid Build Coastguard Worker };
94*b9df5ad1SAndroid Build Coastguard Worker
95*b9df5ad1SAndroid Build Coastguard Worker // check apply with a void function
96*b9df5ad1SAndroid Build Coastguard Worker {
97*b9df5ad1SAndroid Build Coastguard Worker // try to apply with an invalid argument
98*b9df5ad1SAndroid Build Coastguard Worker int value = 0;
99*b9df5ad1SAndroid Build Coastguard Worker
100*b9df5ad1SAndroid Build Coastguard Worker arg = dummy{}; // not an expected type, apply will fail with false.
101*b9df5ad1SAndroid Build Coastguard Worker std::any result;
102*b9df5ad1SAndroid Build Coastguard Worker
103*b9df5ad1SAndroid Build Coastguard Worker ASSERT_FALSE(primitive_metadata_types::apply([&](auto *t __attribute__((unused))) {
104*b9df5ad1SAndroid Build Coastguard Worker value++;
105*b9df5ad1SAndroid Build Coastguard Worker }, &arg, &result));
106*b9df5ad1SAndroid Build Coastguard Worker
107*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(0, value); // never invoked.
108*b9df5ad1SAndroid Build Coastguard Worker ASSERT_FALSE(result.has_value()); // no value returned.
109*b9df5ad1SAndroid Build Coastguard Worker
110*b9df5ad1SAndroid Build Coastguard Worker // try to apply with a valid argument.
111*b9df5ad1SAndroid Build Coastguard Worker arg = (int)1;
112*b9df5ad1SAndroid Build Coastguard Worker
113*b9df5ad1SAndroid Build Coastguard Worker ASSERT_TRUE(primitive_metadata_types::apply([&](auto *t __attribute__((unused))) {
114*b9df5ad1SAndroid Build Coastguard Worker value++;
115*b9df5ad1SAndroid Build Coastguard Worker }, &arg, &result));
116*b9df5ad1SAndroid Build Coastguard Worker
117*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(1, value); // invoked once.
118*b9df5ad1SAndroid Build Coastguard Worker ASSERT_FALSE(result.has_value()); // no value returned (function returns void).
119*b9df5ad1SAndroid Build Coastguard Worker }
120*b9df5ad1SAndroid Build Coastguard Worker
121*b9df5ad1SAndroid Build Coastguard Worker // check apply with a function that returns 2.
122*b9df5ad1SAndroid Build Coastguard Worker {
123*b9df5ad1SAndroid Build Coastguard Worker int value = 0;
124*b9df5ad1SAndroid Build Coastguard Worker arg = (int)1;
125*b9df5ad1SAndroid Build Coastguard Worker std::any result;
126*b9df5ad1SAndroid Build Coastguard Worker
127*b9df5ad1SAndroid Build Coastguard Worker ASSERT_TRUE(primitive_metadata_types::apply([&](auto *t __attribute__((unused))) {
128*b9df5ad1SAndroid Build Coastguard Worker value++;
129*b9df5ad1SAndroid Build Coastguard Worker return (int32_t)2;
130*b9df5ad1SAndroid Build Coastguard Worker }, &arg, &result));
131*b9df5ad1SAndroid Build Coastguard Worker
132*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(1, value); // invoked once.
133*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(2, std::any_cast<int32_t>(result)); // 2 returned
134*b9df5ad1SAndroid Build Coastguard Worker }
135*b9df5ad1SAndroid Build Coastguard Worker
136*b9df5ad1SAndroid Build Coastguard Worker #ifdef METADATA_TESTING
137*b9df5ad1SAndroid Build Coastguard Worker // Checks the number of moves versus copies as the datum flows through Data.
138*b9df5ad1SAndroid Build Coastguard Worker // the counters should increment each time a MoveCount gets copied or
139*b9df5ad1SAndroid Build Coastguard Worker // moved.
140*b9df5ad1SAndroid Build Coastguard Worker
141*b9df5ad1SAndroid Build Coastguard Worker // Datum mc = MoveCount();
142*b9df5ad1SAndroid Build Coastguard Worker
143*b9df5ad1SAndroid Build Coastguard Worker Datum mc{MoveCount()};
144*b9df5ad1SAndroid Build Coastguard Worker ASSERT_TRUE(1 >= std::any_cast<MoveCount>(mc).mMoveCount); // no more than 1 move.
145*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(0, std::any_cast<MoveCount>(&mc)->mCopyCount); // no copies
146*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(1, std::any_cast<MoveCount>(mc).mCopyCount); // Note: any_cast on value copies.
147*b9df5ad1SAndroid Build Coastguard Worker
148*b9df5ad1SAndroid Build Coastguard Worker
149*b9df5ad1SAndroid Build Coastguard Worker // serialize
150*b9df5ad1SAndroid Build Coastguard Worker ByteString bs;
151*b9df5ad1SAndroid Build Coastguard Worker ASSERT_TRUE(copyToByteString(mc, bs));
152*b9df5ad1SAndroid Build Coastguard Worker // deserialize
153*b9df5ad1SAndroid Build Coastguard Worker size_t idx = 0;
154*b9df5ad1SAndroid Build Coastguard Worker Datum parceled;
155*b9df5ad1SAndroid Build Coastguard Worker ASSERT_TRUE(copyFromByteString(&parceled, bs, idx, nullptr /* unknowns */));
156*b9df5ad1SAndroid Build Coastguard Worker
157*b9df5ad1SAndroid Build Coastguard Worker // everything OK with the received data?
158*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(bs.size(), idx); // no data left over.
159*b9df5ad1SAndroid Build Coastguard Worker ASSERT_TRUE(parceled.has_value()); // we have a value.
160*b9df5ad1SAndroid Build Coastguard Worker
161*b9df5ad1SAndroid Build Coastguard Worker // confirm no copies.
162*b9df5ad1SAndroid Build Coastguard Worker ASSERT_TRUE(2 >= std::any_cast<MoveCount>(&parceled)->mMoveCount); // no more than 2 moves.
163*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(0, std::any_cast<MoveCount>(&parceled)->mCopyCount);
164*b9df5ad1SAndroid Build Coastguard Worker #endif
165*b9df5ad1SAndroid Build Coastguard Worker }
166*b9df5ad1SAndroid Build Coastguard Worker
TEST(metadata_tests,basic_data)167*b9df5ad1SAndroid Build Coastguard Worker TEST(metadata_tests, basic_data) {
168*b9df5ad1SAndroid Build Coastguard Worker Data d;
169*b9df5ad1SAndroid Build Coastguard Worker d.emplace("int32", (int32_t)1);
170*b9df5ad1SAndroid Build Coastguard Worker d.emplace("int64", (int64_t)2);
171*b9df5ad1SAndroid Build Coastguard Worker d.emplace("float", (float)3.1f);
172*b9df5ad1SAndroid Build Coastguard Worker d.emplace("double", (double)4.11);
173*b9df5ad1SAndroid Build Coastguard Worker d.emplace("string", "hello");
174*b9df5ad1SAndroid Build Coastguard Worker d["string2"] = "world";
175*b9df5ad1SAndroid Build Coastguard Worker
176*b9df5ad1SAndroid Build Coastguard Worker // Put with typed keys
177*b9df5ad1SAndroid Build Coastguard Worker d.put(MY_NAME_IS, "neo");
178*b9df5ad1SAndroid Build Coastguard Worker d[ITS_NAME_IS] = "spot";
179*b9df5ad1SAndroid Build Coastguard Worker
180*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(1, std::any_cast<int32_t>(d["int32"]));
181*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(2, std::any_cast<int64_t>(d["int64"]));
182*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(3.1f, std::any_cast<float>(d["float"]));
183*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(4.11, std::any_cast<double>(d["double"]));
184*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ("hello", std::any_cast<std::string>(d["string"]));
185*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ("world", std::any_cast<std::string>(d["string2"]));
186*b9df5ad1SAndroid Build Coastguard Worker
187*b9df5ad1SAndroid Build Coastguard Worker // Get with typed keys
188*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ("neo", *d.get_ptr(MY_NAME_IS));
189*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ("spot", *d.get_ptr(ITS_NAME_IS));
190*b9df5ad1SAndroid Build Coastguard Worker
191*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ("neo", d[MY_NAME_IS]);
192*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ("spot", d[ITS_NAME_IS]);
193*b9df5ad1SAndroid Build Coastguard Worker
194*b9df5ad1SAndroid Build Coastguard Worker ByteString bs = byteStringFromData(d);
195*b9df5ad1SAndroid Build Coastguard Worker Data data = dataFromByteString(bs);
196*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ((size_t)8, data.size());
197*b9df5ad1SAndroid Build Coastguard Worker
198*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(1, std::any_cast<int32_t>(data["int32"]));
199*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(2, std::any_cast<int64_t>(data["int64"]));
200*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(3.1f, std::any_cast<float>(data["float"]));
201*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(4.11, std::any_cast<double>(data["double"]));
202*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ("hello", std::any_cast<std::string>(data["string"]));
203*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ("neo", *data.get_ptr(MY_NAME_IS));
204*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ("spot", *data.get_ptr(ITS_NAME_IS));
205*b9df5ad1SAndroid Build Coastguard Worker
206*b9df5ad1SAndroid Build Coastguard Worker data[MY_NAME_IS] = "one";
207*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ("one", data[MY_NAME_IS]);
208*b9df5ad1SAndroid Build Coastguard Worker
209*b9df5ad1SAndroid Build Coastguard Worker // Keys are typed, so this fails to compile.
210*b9df5ad1SAndroid Build Coastguard Worker // data->put(MY_NAME_IS, 10);
211*b9df5ad1SAndroid Build Coastguard Worker
212*b9df5ad1SAndroid Build Coastguard Worker #ifdef METADATA_TESTING
213*b9df5ad1SAndroid Build Coastguard Worker // Checks the number of moves versus copies as the Datum goes to
214*b9df5ad1SAndroid Build Coastguard Worker // Data and then parceled and unparceled.
215*b9df5ad1SAndroid Build Coastguard Worker // The counters should increment each time a MoveCount gets copied or
216*b9df5ad1SAndroid Build Coastguard Worker // moved.
217*b9df5ad1SAndroid Build Coastguard Worker {
218*b9df5ad1SAndroid Build Coastguard Worker Data d2;
219*b9df5ad1SAndroid Build Coastguard Worker d2[MOVE_COUNT] = MoveCount(); // should be moved.
220*b9df5ad1SAndroid Build Coastguard Worker
221*b9df5ad1SAndroid Build Coastguard Worker ASSERT_TRUE(1 >= d2[MOVE_COUNT].mMoveCount); // no more than one move.
222*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(0, d2[MOVE_COUNT].mCopyCount); // no copies
223*b9df5ad1SAndroid Build Coastguard Worker
224*b9df5ad1SAndroid Build Coastguard Worker ByteString bs = byteStringFromData(d2);
225*b9df5ad1SAndroid Build Coastguard Worker Data d3 = dataFromByteString(bs);
226*b9df5ad1SAndroid Build Coastguard Worker
227*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(0, d3[MOVE_COUNT].mCopyCount); // no copies
228*b9df5ad1SAndroid Build Coastguard Worker ASSERT_TRUE(2 >= d3[MOVE_COUNT].mMoveCount); // no more than 2 moves after parceling
229*b9df5ad1SAndroid Build Coastguard Worker }
230*b9df5ad1SAndroid Build Coastguard Worker #endif
231*b9df5ad1SAndroid Build Coastguard Worker }
232*b9df5ad1SAndroid Build Coastguard Worker
TEST(metadata_tests,complex_data)233*b9df5ad1SAndroid Build Coastguard Worker TEST(metadata_tests, complex_data) {
234*b9df5ad1SAndroid Build Coastguard Worker Data small;
235*b9df5ad1SAndroid Build Coastguard Worker Data big;
236*b9df5ad1SAndroid Build Coastguard Worker
237*b9df5ad1SAndroid Build Coastguard Worker small[MY_NAME_IS] = "abc";
238*b9df5ad1SAndroid Build Coastguard Worker #ifdef METADATA_TESTING
239*b9df5ad1SAndroid Build Coastguard Worker small[MOVE_COUNT] = MoveCount{};
240*b9df5ad1SAndroid Build Coastguard Worker #endif
241*b9df5ad1SAndroid Build Coastguard Worker big[TABLE] = small; // ONE COPY HERE of the MoveCount (embedded in small).
242*b9df5ad1SAndroid Build Coastguard Worker
243*b9df5ad1SAndroid Build Coastguard Worker #ifdef METADATA_TESTING
244*b9df5ad1SAndroid Build Coastguard Worker big[VECTOR] = std::vector<Datum>{small, small};
245*b9df5ad1SAndroid Build Coastguard Worker big[PAIR] = std::make_pair<Datum, Datum>(small, small);
246*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(1, big[TABLE][MOVE_COUNT].mCopyCount); // one copy done for small.
247*b9df5ad1SAndroid Build Coastguard Worker
248*b9df5ad1SAndroid Build Coastguard Worker big[FUNKY] = std::vector<std::vector<std::pair<std::string, short>>>{
249*b9df5ad1SAndroid Build Coastguard Worker {{"a", 1}, {"b", 2}},
250*b9df5ad1SAndroid Build Coastguard Worker {{"c", 3}, {"d", 4}},
251*b9df5ad1SAndroid Build Coastguard Worker };
252*b9df5ad1SAndroid Build Coastguard Worker
253*b9df5ad1SAndroid Build Coastguard Worker // struct Arbitrary { int i0; std::vector<int> v1; std::pair<int, int> p2; };
254*b9df5ad1SAndroid Build Coastguard Worker big[ARBITRARY] = Arbitrary{0, {1, 2, 3}, {4, 5}};
255*b9df5ad1SAndroid Build Coastguard Worker #endif
256*b9df5ad1SAndroid Build Coastguard Worker
257*b9df5ad1SAndroid Build Coastguard Worker // Try round-trip conversion to a ByteString.
258*b9df5ad1SAndroid Build Coastguard Worker ByteString bs = byteStringFromData(big);
259*b9df5ad1SAndroid Build Coastguard Worker Data data = dataFromByteString(bs);
260*b9df5ad1SAndroid Build Coastguard Worker #ifdef METADATA_TESTING
261*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ((size_t)5, data.size());
262*b9df5ad1SAndroid Build Coastguard Worker #else
263*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ((size_t)1, data.size());
264*b9df5ad1SAndroid Build Coastguard Worker #endif
265*b9df5ad1SAndroid Build Coastguard Worker
266*b9df5ad1SAndroid Build Coastguard Worker // Nested tables make sense.
267*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ("abc", data[TABLE][MY_NAME_IS]);
268*b9df5ad1SAndroid Build Coastguard Worker
269*b9df5ad1SAndroid Build Coastguard Worker #ifdef METADATA_TESTING
270*b9df5ad1SAndroid Build Coastguard Worker // TODO: Maybe we don't need the vector or the pair.
271*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ("abc", std::any_cast<Data>(data[VECTOR][1])[MY_NAME_IS]);
272*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ("abc", std::any_cast<Data>(data[PAIR].first)[MY_NAME_IS]);
273*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(1, data[TABLE][MOVE_COUNT].mCopyCount); // no additional copies.
274*b9df5ad1SAndroid Build Coastguard Worker
275*b9df5ad1SAndroid Build Coastguard Worker auto funky = data[FUNKY];
276*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ("a", funky[0][0].first);
277*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(4, funky[1][1].second);
278*b9df5ad1SAndroid Build Coastguard Worker
279*b9df5ad1SAndroid Build Coastguard Worker auto arbitrary = data[ARBITRARY];
280*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(0, arbitrary.i0);
281*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(2, arbitrary.v1[1]);
282*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(4, arbitrary.p2.first);
283*b9df5ad1SAndroid Build Coastguard Worker #endif
284*b9df5ad1SAndroid Build Coastguard Worker }
285*b9df5ad1SAndroid Build Coastguard Worker
286*b9df5ad1SAndroid Build Coastguard Worker // DO NOT CHANGE THIS after R, but add a new test.
TEST(metadata_tests,compatibility_R)287*b9df5ad1SAndroid Build Coastguard Worker TEST(metadata_tests, compatibility_R) {
288*b9df5ad1SAndroid Build Coastguard Worker Data d;
289*b9df5ad1SAndroid Build Coastguard Worker d.emplace("i32", (int32_t)1);
290*b9df5ad1SAndroid Build Coastguard Worker d.emplace("i64", (int64_t)2);
291*b9df5ad1SAndroid Build Coastguard Worker d.emplace("float", (float)3.1f);
292*b9df5ad1SAndroid Build Coastguard Worker d.emplace("double", (double)4.11);
293*b9df5ad1SAndroid Build Coastguard Worker Data s;
294*b9df5ad1SAndroid Build Coastguard Worker s.emplace("string", "hello");
295*b9df5ad1SAndroid Build Coastguard Worker d.emplace("data", s);
296*b9df5ad1SAndroid Build Coastguard Worker
297*b9df5ad1SAndroid Build Coastguard Worker ByteString bs = byteStringFromData(d);
298*b9df5ad1SAndroid Build Coastguard Worker printf("%s\n", toString(bs).c_str());
299*b9df5ad1SAndroid Build Coastguard Worker
300*b9df5ad1SAndroid Build Coastguard Worker // Since we use a map instead of a hashmap
301*b9df5ad1SAndroid Build Coastguard Worker // layout order of elements is precisely defined.
302*b9df5ad1SAndroid Build Coastguard Worker ByteString reference = {
303*b9df5ad1SAndroid Build Coastguard Worker 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
304*b9df5ad1SAndroid Build Coastguard Worker 0x64, 0x61, 0x74, 0x61, 0x06, 0x00, 0x00, 0x00,
305*b9df5ad1SAndroid Build Coastguard Worker 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
306*b9df5ad1SAndroid Build Coastguard Worker 0x06, 0x00, 0x00, 0x00, 0x73, 0x74, 0x72, 0x69,
307*b9df5ad1SAndroid Build Coastguard Worker 0x6e, 0x67, 0x05, 0x00, 0x00, 0x00, 0x09, 0x00,
308*b9df5ad1SAndroid Build Coastguard Worker 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x68, 0x65,
309*b9df5ad1SAndroid Build Coastguard Worker 0x6c, 0x6c, 0x6f, 0x06, 0x00, 0x00, 0x00, 0x64,
310*b9df5ad1SAndroid Build Coastguard Worker 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x04, 0x00, 0x00,
311*b9df5ad1SAndroid Build Coastguard Worker 0x00, 0x08, 0x00, 0x00, 0x00, 0x71, 0x3d, 0x0a,
312*b9df5ad1SAndroid Build Coastguard Worker 0xd7, 0xa3, 0x70, 0x10, 0x40, 0x05, 0x00, 0x00,
313*b9df5ad1SAndroid Build Coastguard Worker 0x00, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x03, 0x00,
314*b9df5ad1SAndroid Build Coastguard Worker 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x66, 0x66,
315*b9df5ad1SAndroid Build Coastguard Worker 0x46, 0x40, 0x03, 0x00, 0x00, 0x00, 0x69, 0x33,
316*b9df5ad1SAndroid Build Coastguard Worker 0x32, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
317*b9df5ad1SAndroid Build Coastguard Worker 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
318*b9df5ad1SAndroid Build Coastguard Worker 0x00, 0x69, 0x36, 0x34, 0x02, 0x00, 0x00, 0x00,
319*b9df5ad1SAndroid Build Coastguard Worker 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
320*b9df5ad1SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00
321*b9df5ad1SAndroid Build Coastguard Worker };
322*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(reference, bs);
323*b9df5ad1SAndroid Build Coastguard Worker
324*b9df5ad1SAndroid Build Coastguard Worker Data decoded = dataFromByteString(bs);
325*b9df5ad1SAndroid Build Coastguard Worker
326*b9df5ad1SAndroid Build Coastguard Worker // TODO: data equality.
327*b9df5ad1SAndroid Build Coastguard Worker // ASSERT_EQ(decoded, d);
328*b9df5ad1SAndroid Build Coastguard Worker
329*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(1, std::any_cast<int32_t>(decoded["i32"]));
330*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(2, std::any_cast<int64_t>(decoded["i64"]));
331*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(3.1f, std::any_cast<float>(decoded["float"]));
332*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(4.11, std::any_cast<double>(decoded["double"]));
333*b9df5ad1SAndroid Build Coastguard Worker Data decoded_s = std::any_cast<Data>(decoded["data"]);
334*b9df5ad1SAndroid Build Coastguard Worker
335*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ("hello", std::any_cast<std::string>(s["string"]));
336*b9df5ad1SAndroid Build Coastguard Worker
337*b9df5ad1SAndroid Build Coastguard Worker {
338*b9df5ad1SAndroid Build Coastguard Worker ByteString unknownData = reference;
339*b9df5ad1SAndroid Build Coastguard Worker unknownData[12] = 0xff;
340*b9df5ad1SAndroid Build Coastguard Worker Data decoded2 = dataFromByteString(unknownData);
341*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ((size_t)0, decoded2.size());
342*b9df5ad1SAndroid Build Coastguard Worker
343*b9df5ad1SAndroid Build Coastguard Worker ByteStringUnknowns unknowns;
344*b9df5ad1SAndroid Build Coastguard Worker Data decoded3 = dataFromByteString(unknownData, &unknowns);
345*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ((size_t)4, decoded3.size());
346*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ((size_t)1, unknowns.size());
347*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ((unsigned)0xff, unknowns[0]);
348*b9df5ad1SAndroid Build Coastguard Worker }
349*b9df5ad1SAndroid Build Coastguard Worker
350*b9df5ad1SAndroid Build Coastguard Worker {
351*b9df5ad1SAndroid Build Coastguard Worker ByteString unknownDouble = reference;
352*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(0x4, unknownDouble[0x3d]);
353*b9df5ad1SAndroid Build Coastguard Worker unknownDouble[0x3d] = 0xfe;
354*b9df5ad1SAndroid Build Coastguard Worker Data decoded2 = dataFromByteString(unknownDouble);
355*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ((size_t)0, decoded2.size());
356*b9df5ad1SAndroid Build Coastguard Worker
357*b9df5ad1SAndroid Build Coastguard Worker ByteStringUnknowns unknowns;
358*b9df5ad1SAndroid Build Coastguard Worker Data decoded3 = dataFromByteString(unknownDouble, &unknowns);
359*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ((size_t)4, decoded3.size());
360*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ((size_t)1, unknowns.size());
361*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ((unsigned)0xfe, unknowns[0]);
362*b9df5ad1SAndroid Build Coastguard Worker }
363*b9df5ad1SAndroid Build Coastguard Worker };
364*b9df5ad1SAndroid Build Coastguard Worker
TEST(metadata_tests,bytestring_examples)365*b9df5ad1SAndroid Build Coastguard Worker TEST(metadata_tests, bytestring_examples) {
366*b9df5ad1SAndroid Build Coastguard Worker ByteString bs;
367*b9df5ad1SAndroid Build Coastguard Worker
368*b9df5ad1SAndroid Build Coastguard Worker copyToByteString((int32_t)123, bs);
369*b9df5ad1SAndroid Build Coastguard Worker printf("123 -> %s\n", toString(bs).c_str());
370*b9df5ad1SAndroid Build Coastguard Worker const ByteString ref1{ 0x7b, 0x00, 0x00, 0x00 };
371*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(ref1, bs);
372*b9df5ad1SAndroid Build Coastguard Worker
373*b9df5ad1SAndroid Build Coastguard Worker bs.clear();
374*b9df5ad1SAndroid Build Coastguard Worker // for copyToByteString use std::string instead of char array.
375*b9df5ad1SAndroid Build Coastguard Worker copyToByteString(std::string("hi"), bs);
376*b9df5ad1SAndroid Build Coastguard Worker printf("\"hi\" -> %s\n", toString(bs).c_str());
377*b9df5ad1SAndroid Build Coastguard Worker const ByteString ref2{ 0x02, 0x00, 0x00, 0x00, 0x68, 0x69 };
378*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(ref2, bs);
379*b9df5ad1SAndroid Build Coastguard Worker
380*b9df5ad1SAndroid Build Coastguard Worker bs.clear();
381*b9df5ad1SAndroid Build Coastguard Worker Data d;
382*b9df5ad1SAndroid Build Coastguard Worker d.emplace("hello", "world");
383*b9df5ad1SAndroid Build Coastguard Worker d.emplace("value", (int32_t)1000);
384*b9df5ad1SAndroid Build Coastguard Worker copyToByteString(d, bs);
385*b9df5ad1SAndroid Build Coastguard Worker printf("{{\"hello\", \"world\"}, {\"value\", 1000}} -> %s\n", toString(bs).c_str());
386*b9df5ad1SAndroid Build Coastguard Worker const ByteString ref3{
387*b9df5ad1SAndroid Build Coastguard Worker 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
388*b9df5ad1SAndroid Build Coastguard Worker 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x05, 0x00, 0x00,
389*b9df5ad1SAndroid Build Coastguard Worker 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
390*b9df5ad1SAndroid Build Coastguard Worker 0x00, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x05, 0x00,
391*b9df5ad1SAndroid Build Coastguard Worker 0x00, 0x00, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x01,
392*b9df5ad1SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe8,
393*b9df5ad1SAndroid Build Coastguard Worker 0x03, 0x00, 0x00};
394*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(ref3, bs);
395*b9df5ad1SAndroid Build Coastguard Worker };
396*b9df5ad1SAndroid Build Coastguard Worker
397*b9df5ad1SAndroid Build Coastguard Worker // Test C API from C++
TEST(metadata_tests,c)398*b9df5ad1SAndroid Build Coastguard Worker TEST(metadata_tests, c) {
399*b9df5ad1SAndroid Build Coastguard Worker audio_metadata_t *metadata = audio_metadata_create();
400*b9df5ad1SAndroid Build Coastguard Worker Data d;
401*b9df5ad1SAndroid Build Coastguard Worker d.emplace("i32", (int32_t)1);
402*b9df5ad1SAndroid Build Coastguard Worker d.emplace("i64", (int64_t)2);
403*b9df5ad1SAndroid Build Coastguard Worker d.emplace("float", (float)3.1f);
404*b9df5ad1SAndroid Build Coastguard Worker d.emplace("double", (double)4.11);
405*b9df5ad1SAndroid Build Coastguard Worker Data s;
406*b9df5ad1SAndroid Build Coastguard Worker s.emplace("string", "hello");
407*b9df5ad1SAndroid Build Coastguard Worker d.emplace("data", s);
408*b9df5ad1SAndroid Build Coastguard Worker
409*b9df5ad1SAndroid Build Coastguard Worker audio_metadata_put(metadata, "i32", (int32_t)1);
410*b9df5ad1SAndroid Build Coastguard Worker audio_metadata_put(metadata, "i64", (int64_t)2);
411*b9df5ad1SAndroid Build Coastguard Worker audio_metadata_put(metadata, "float", (float)3.1f);
412*b9df5ad1SAndroid Build Coastguard Worker audio_metadata_put(metadata, "double", (double)4.11);
413*b9df5ad1SAndroid Build Coastguard Worker audio_metadata_t *data = audio_metadata_create();
414*b9df5ad1SAndroid Build Coastguard Worker audio_metadata_put(data, "string", "hello");
415*b9df5ad1SAndroid Build Coastguard Worker audio_metadata_put(metadata, "data", data);
416*b9df5ad1SAndroid Build Coastguard Worker #if 0 // candidate function not viable: no known conversion
417*b9df5ad1SAndroid Build Coastguard Worker {
418*b9df5ad1SAndroid Build Coastguard Worker static const struct complex {
419*b9df5ad1SAndroid Build Coastguard Worker float re;
420*b9df5ad1SAndroid Build Coastguard Worker float im;
421*b9df5ad1SAndroid Build Coastguard Worker } prime = { -5.0, -4.0 };
422*b9df5ad1SAndroid Build Coastguard Worker audio_metadata_put(metadata, "complex", prime);
423*b9df5ad1SAndroid Build Coastguard Worker }
424*b9df5ad1SAndroid Build Coastguard Worker #endif
425*b9df5ad1SAndroid Build Coastguard Worker audio_metadata_destroy(data);
426*b9df5ad1SAndroid Build Coastguard Worker
427*b9df5ad1SAndroid Build Coastguard Worker int32_t i32Val;
428*b9df5ad1SAndroid Build Coastguard Worker int64_t i64Val;
429*b9df5ad1SAndroid Build Coastguard Worker float floatVal;
430*b9df5ad1SAndroid Build Coastguard Worker double doubleVal;
431*b9df5ad1SAndroid Build Coastguard Worker char *strVal = nullptr;
432*b9df5ad1SAndroid Build Coastguard Worker audio_metadata_t *dataVal = nullptr;
433*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(0, audio_metadata_get(metadata, "i32", &i32Val));
434*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(1, i32Val);
435*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(0, audio_metadata_get(metadata, "i64", &i64Val));
436*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(2, i64Val);
437*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(0, audio_metadata_get(metadata, "float", &floatVal));
438*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(3.1f, floatVal);
439*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(0, audio_metadata_get(metadata, "double", &doubleVal));
440*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(4.11, doubleVal);
441*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(0, audio_metadata_get(metadata, "data", &dataVal));
442*b9df5ad1SAndroid Build Coastguard Worker ASSERT_NE(dataVal, nullptr);
443*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(0, audio_metadata_get(dataVal, "string", &strVal));
444*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(0, strcmp("hello", strVal));
445*b9df5ad1SAndroid Build Coastguard Worker free(strVal);
446*b9df5ad1SAndroid Build Coastguard Worker audio_metadata_destroy(dataVal);
447*b9df5ad1SAndroid Build Coastguard Worker dataVal = nullptr;
448*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(-ENOENT, audio_metadata_get(metadata, "non_exist_key", &i32Val));
449*b9df5ad1SAndroid Build Coastguard Worker audio_metadata_t *nullMetadata = nullptr;
450*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(-EINVAL, audio_metadata_get(nullMetadata, "i32", &i32Val));
451*b9df5ad1SAndroid Build Coastguard Worker char *nullKey = nullptr;
452*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(-EINVAL, audio_metadata_get(metadata, nullKey, &i32Val));
453*b9df5ad1SAndroid Build Coastguard Worker int *nullI32Val = nullptr;
454*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(-EINVAL, audio_metadata_get(metadata, "i32", nullI32Val));
455*b9df5ad1SAndroid Build Coastguard Worker
456*b9df5ad1SAndroid Build Coastguard Worker uint8_t *bs = nullptr;
457*b9df5ad1SAndroid Build Coastguard Worker ssize_t length = byte_string_from_audio_metadata(metadata, &bs);
458*b9df5ad1SAndroid Build Coastguard Worker ASSERT_GT(length, 0); // if gt 0, the bs has been updated to a new value.
459*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ((size_t)length, audio_metadata_byte_string_len(bs));
460*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ((size_t)length, dataByteStringLen(bs));
461*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(byteStringFromData(d).size(), ByteString(bs, bs + length).size());
462*b9df5ad1SAndroid Build Coastguard Worker audio_metadata_t *metadataFromBs = audio_metadata_from_byte_string(bs, length);
463*b9df5ad1SAndroid Build Coastguard Worker free(bs);
464*b9df5ad1SAndroid Build Coastguard Worker bs = nullptr;
465*b9df5ad1SAndroid Build Coastguard Worker length = byte_string_from_audio_metadata(metadataFromBs, &bs);
466*b9df5ad1SAndroid Build Coastguard Worker ASSERT_GT(length, 0); // if gt 0, the bs has been updated to a new value.
467*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(byteStringFromData(d), ByteString(bs, bs + length));
468*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ((size_t)length, audio_metadata_byte_string_len(bs));
469*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ((size_t)length, dataByteStringLen(bs));
470*b9df5ad1SAndroid Build Coastguard Worker free(bs);
471*b9df5ad1SAndroid Build Coastguard Worker bs = nullptr;
472*b9df5ad1SAndroid Build Coastguard Worker audio_metadata_destroy(metadataFromBs);
473*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(-EINVAL, byte_string_from_audio_metadata(nullMetadata, &bs));
474*b9df5ad1SAndroid Build Coastguard Worker uint8_t **nullBs = nullptr;
475*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(-EINVAL, byte_string_from_audio_metadata(metadata, nullBs));
476*b9df5ad1SAndroid Build Coastguard Worker
477*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(1, audio_metadata_erase(metadata, "data"));
478*b9df5ad1SAndroid Build Coastguard Worker // initialize to a known invalid pointer
479*b9df5ad1SAndroid Build Coastguard Worker dataVal = reinterpret_cast<audio_metadata_t *>(reinterpret_cast<intptr_t>(nullptr) + 1);
480*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(-ENOENT, audio_metadata_get(metadata, "data", &dataVal));
481*b9df5ad1SAndroid Build Coastguard Worker // confirm that a failed get will assign nullptr; be sure to
482*b9df5ad1SAndroid Build Coastguard Worker // update test if API behavior is changed to not assign nullptr on error
483*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, dataVal);
484*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(0, audio_metadata_erase(metadata, "data"));
485*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(-EINVAL, audio_metadata_erase(nullMetadata, "key"));
486*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(-EINVAL, audio_metadata_erase(metadata, nullKey));
487*b9df5ad1SAndroid Build Coastguard Worker
488*b9df5ad1SAndroid Build Coastguard Worker audio_metadata_destroy(metadata);
489*b9df5ad1SAndroid Build Coastguard Worker };
490*b9df5ad1SAndroid Build Coastguard Worker
TEST(metadata_tests,empty_data_c)491*b9df5ad1SAndroid Build Coastguard Worker TEST(metadata_tests, empty_data_c) {
492*b9df5ad1SAndroid Build Coastguard Worker std::unique_ptr<audio_metadata_t, decltype(&audio_metadata_destroy)>
493*b9df5ad1SAndroid Build Coastguard Worker metadata{audio_metadata_create(), audio_metadata_destroy}; // empty metadata container.
494*b9df5ad1SAndroid Build Coastguard Worker uint8_t *bs = nullptr;
495*b9df5ad1SAndroid Build Coastguard Worker ssize_t length = byte_string_from_audio_metadata(metadata.get(), &bs);
496*b9df5ad1SAndroid Build Coastguard Worker ASSERT_GT(length, 0); // if gt 0, the bs has been updated to a new value.
497*b9df5ad1SAndroid Build Coastguard Worker std::unique_ptr<uint8_t, decltype(&free)> bs_scoped_deleter{bs, free};
498*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ((size_t)length, audio_metadata_byte_string_len(bs));
499*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ((size_t)length, dataByteStringLen(bs));
500*b9df5ad1SAndroid Build Coastguard Worker
501*b9df5ad1SAndroid Build Coastguard Worker Data d; // empty metadata container.
502*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(byteStringFromData(d).size(), ByteString(bs, bs + length).size());
503*b9df5ad1SAndroid Build Coastguard Worker std::unique_ptr<audio_metadata_t, decltype(&audio_metadata_destroy)>
504*b9df5ad1SAndroid Build Coastguard Worker metadataFromBs{audio_metadata_from_byte_string(bs, length), audio_metadata_destroy};
505*b9df5ad1SAndroid Build Coastguard Worker length = byte_string_from_audio_metadata(metadataFromBs.get(), &bs);
506*b9df5ad1SAndroid Build Coastguard Worker ASSERT_GT(length, 0); // if gt 0, the bs has been updated to a new value.
507*b9df5ad1SAndroid Build Coastguard Worker bs_scoped_deleter.reset(bs);
508*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ(byteStringFromData(d), ByteString(bs, bs + length));
509*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ((size_t)length, audio_metadata_byte_string_len(bs));
510*b9df5ad1SAndroid Build Coastguard Worker ASSERT_EQ((size_t)length, dataByteStringLen(bs));
511*b9df5ad1SAndroid Build Coastguard Worker };
512