Snap for 7336869 from 0311d9c497b1ae80b1343ce804de62331630ee5d to sc-v2-release
Change-Id: I4e78fc70d453530b0d189845161ed2dfcf9cd389
diff --git a/audio_utils/Metadata.cpp b/audio_utils/Metadata.cpp
index f38c8bf..d580f4c 100644
--- a/audio_utils/Metadata.cpp
+++ b/audio_utils/Metadata.cpp
@@ -185,3 +185,7 @@
memcpy(*byteString, bs.c_str(), bs.size());
return bs.size();
}
+
+size_t audio_metadata_byte_string_len(const uint8_t *byteString) {
+ return dataByteStringLen(byteString);
+}
diff --git a/audio_utils/include/audio_utils/Metadata.h b/audio_utils/include/audio_utils/Metadata.h
index f1990b2..2f1edb3 100644
--- a/audio_utils/include/audio_utils/Metadata.h
+++ b/audio_utils/include/audio_utils/Metadata.h
@@ -905,6 +905,43 @@
return bs; // copy elision
}
+/**
+ * \brief Returns the length of the byte string buffer from the raw pointer.
+ *
+ * The raw pointer comes from the Data object's ByteString.data()
+ * or from the C API byte_string_from_audio_metadata().
+ * This is a helper method for C implementations which may pass the raw
+ * byte string buffer pointer (which does not directly contain the length).
+ * C++ methods should always use the ByteString object.
+ *
+ * \param byteString byte string buffer raw pointer.
+ * \return size in bytes of metadata in the buffer or 0 if something went wrong.
+ */
+
+inline size_t dataByteStringLen(const uint8_t *ptr) {
+ index_size_t elements;
+ const uint8_t * const origPtr = ptr;
+ memcpy(&elements, ptr, sizeof(elements));
+ ptr += sizeof(elements);
+ for (index_size_t i = 0; i < elements; ++i) {
+ // get key (string)
+ index_size_t keyLen;
+ memcpy(&keyLen, ptr, sizeof(keyLen));
+ ptr += keyLen + sizeof(keyLen);
+ // get type
+ type_size_t type;
+ memcpy(&type, ptr, sizeof(type));
+ ptr += sizeof(type_size_t);
+ // Note: could check type validity.
+ // payload size
+ datum_size_t datumSize;
+ memcpy(&datumSize, ptr, sizeof(datumSize));
+ ptr += datumSize + sizeof(datumSize);
+ }
+ const ptrdiff_t size = ptr - origPtr;
+ return size < 0 ? 0 : size;
+}
+
} // namespace android::audio_utils::metadata
#endif // __cplusplus
@@ -1169,6 +1206,16 @@
*/
ssize_t byte_string_from_audio_metadata(audio_metadata_t *metadata, uint8_t **byteString);
+/**
+ * \brief Return the size in bytes of the metadata byte string
+ *
+ * Note: strlen() cannot be used as there are embedded 0's in the byte string.
+ *
+ * \param byteString a valid byte string buffer from byte_string_from_audio_metadata().
+ * \return size in bytes of metadata in the buffer or 0 if something went wrong.
+ */
+size_t audio_metadata_byte_string_len(const uint8_t *byteString);
+
/** \cond */
__END_DECLS
/** \endcond */
diff --git a/audio_utils/tests/metadata_tests.cpp b/audio_utils/tests/metadata_tests.cpp
index 6ac6726..3856dc0 100644
--- a/audio_utils/tests/metadata_tests.cpp
+++ b/audio_utils/tests/metadata_tests.cpp
@@ -454,13 +454,19 @@
ASSERT_EQ(-EINVAL, audio_metadata_get(metadata, "i32", nullI32Val));
uint8_t *bs = nullptr;
- size_t length = byte_string_from_audio_metadata(metadata, &bs);
+ ssize_t length = byte_string_from_audio_metadata(metadata, &bs);
+ ASSERT_GT(length, 0); // if gt 0, the bs has been updated to a new value.
+ ASSERT_EQ((size_t)length, audio_metadata_byte_string_len(bs));
+ ASSERT_EQ((size_t)length, dataByteStringLen(bs));
ASSERT_EQ(byteStringFromData(d).size(), ByteString(bs, length).size());
audio_metadata_t *metadataFromBs = audio_metadata_from_byte_string(bs, length);
free(bs);
bs = nullptr;
length = byte_string_from_audio_metadata(metadataFromBs, &bs);
+ ASSERT_GT(length, 0); // if gt 0, the bs has been updated to a new value.
ASSERT_EQ(byteStringFromData(d), ByteString(bs, length));
+ ASSERT_EQ((size_t)length, audio_metadata_byte_string_len(bs));
+ ASSERT_EQ((size_t)length, dataByteStringLen(bs));
free(bs);
bs = nullptr;
audio_metadata_destroy(metadataFromBs);
@@ -481,3 +487,25 @@
audio_metadata_destroy(metadata);
};
+
+TEST(metadata_tests, empty_data_c) {
+ std::unique_ptr<audio_metadata_t, decltype(&audio_metadata_destroy)>
+ metadata{audio_metadata_create(), audio_metadata_destroy}; // empty metadata container.
+ uint8_t *bs = nullptr;
+ ssize_t length = byte_string_from_audio_metadata(metadata.get(), &bs);
+ ASSERT_GT(length, 0); // if gt 0, the bs has been updated to a new value.
+ std::unique_ptr<uint8_t, decltype(&free)> bs_scoped_deleter{bs, free};
+ ASSERT_EQ((size_t)length, audio_metadata_byte_string_len(bs));
+ ASSERT_EQ((size_t)length, dataByteStringLen(bs));
+
+ Data d; // empty metadata container.
+ ASSERT_EQ(byteStringFromData(d).size(), ByteString(bs, length).size());
+ std::unique_ptr<audio_metadata_t, decltype(&audio_metadata_destroy)>
+ metadataFromBs{audio_metadata_from_byte_string(bs, length), audio_metadata_destroy};
+ length = byte_string_from_audio_metadata(metadataFromBs.get(), &bs);
+ ASSERT_GT(length, 0); // if gt 0, the bs has been updated to a new value.
+ bs_scoped_deleter.reset(bs);
+ ASSERT_EQ(byteStringFromData(d), ByteString(bs, length));
+ ASSERT_EQ((size_t)length, audio_metadata_byte_string_len(bs));
+ ASSERT_EQ((size_t)length, dataByteStringLen(bs));
+};