From ff73463d0b7cbcb675ab401deb9d7997043543b4 Mon Sep 17 00:00:00 2001 From: "John \"Juce\" Bruce" Date: Mon, 14 Nov 2022 21:20:40 -0800 Subject: [PATCH] Add String Formatting Util (Merged from http://go/wvgerrit/160042.) Since we don't have access to std::format yet, this patch adds a function to wvutil to format text into a std::string. Bug: 255466913 Test: x86-64 Test: raven Change-Id: I28043da76af5b4772a29fa7e7241343caf9b54a1 --- libwvdrmengine/Android.bp | 1 + libwvdrmengine/cdm/test/coverage-test.mk | 1 + .../cdm/util/include/string_format.h | 18 ++++++ libwvdrmengine/cdm/util/src/string_format.cpp | 40 ++++++++++++ .../cdm/util/test/string_format_unittest.cpp | 64 +++++++++++++++++++ 5 files changed, 124 insertions(+) create mode 100644 libwvdrmengine/cdm/util/include/string_format.h create mode 100644 libwvdrmengine/cdm/util/src/string_format.cpp create mode 100644 libwvdrmengine/cdm/util/test/string_format_unittest.cpp diff --git a/libwvdrmengine/Android.bp b/libwvdrmengine/Android.bp index 41107add..6c7ab650 100644 --- a/libwvdrmengine/Android.bp +++ b/libwvdrmengine/Android.bp @@ -309,6 +309,7 @@ cdm_util_src_files = [ "cdm/util/src/platform.cpp", "cdm/util/src/rw_lock.cpp", "cdm/util/src/string_conversions.cpp", + "cdm/util/src/string_format.cpp", ] cc_library_static { diff --git a/libwvdrmengine/cdm/test/coverage-test.mk b/libwvdrmengine/cdm/test/coverage-test.mk index 66102d86..571c657a 100644 --- a/libwvdrmengine/cdm/test/coverage-test.mk +++ b/libwvdrmengine/cdm/test/coverage-test.mk @@ -41,6 +41,7 @@ LOCAL_SRC_FILES := \ ../util/test/cdm_random_unittest.cpp \ ../util/test/file_store_unittest.cpp \ ../util/test/file_utils_unittest.cpp \ + ../util/test/string_format_unittest.cpp \ ../util/test/test_sleep.cpp \ ../../oemcrypto/test/oec_device_features.cpp \ ../../oemcrypto/test/oec_key_deriver.cpp \ diff --git a/libwvdrmengine/cdm/util/include/string_format.h b/libwvdrmengine/cdm/util/include/string_format.h new file mode 100644 index 00000000..62f9fd91 --- /dev/null +++ b/libwvdrmengine/cdm/util/include/string_format.h @@ -0,0 +1,18 @@ +// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine License +// Agreement. +#ifndef WVCDM_UTIL_STRING_FORMAT_H_ +#define WVCDM_UTIL_STRING_FORMAT_H_ + +#include + +namespace wvutil { + +#ifdef __GNUC__ +[[gnu::format(printf, 2, 3)]] +#endif +bool FormatString(std::string* out, const char* fmt, ...); + +} // namespace wvutil + +#endif // WVCDM_UTIL_STRING_FORMAT_H_ diff --git a/libwvdrmengine/cdm/util/src/string_format.cpp b/libwvdrmengine/cdm/util/src/string_format.cpp new file mode 100644 index 00000000..91cce37e --- /dev/null +++ b/libwvdrmengine/cdm/util/src/string_format.cpp @@ -0,0 +1,40 @@ +// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine License +// Agreement. + +#include "string_format.h" + +#include +#include +#include +#include + +#include + +namespace wvutil { + +bool FormatString(std::string* out, const char* fmt, ...) { + if (out == nullptr || fmt == nullptr) return false; + + va_list ap1; + va_start(ap1, fmt); + const int desired_size = vsnprintf(nullptr, 0, fmt, ap1); + va_end(ap1); + + if (desired_size < 0) return false; + const size_t buffer_size = + static_cast(desired_size) + 1; // +1 for null + std::unique_ptr buffer(new char[buffer_size]); + + va_list ap2; + va_start(ap2, fmt); + const int actual_size = vsnprintf(buffer.get(), buffer_size, fmt, ap2); + va_end(ap2); + + if (actual_size != desired_size) return false; + + out->assign(buffer.get(), actual_size); + return true; +} + +} // namespace wvutil diff --git a/libwvdrmengine/cdm/util/test/string_format_unittest.cpp b/libwvdrmengine/cdm/util/test/string_format_unittest.cpp new file mode 100644 index 00000000..282a43d2 --- /dev/null +++ b/libwvdrmengine/cdm/util/test/string_format_unittest.cpp @@ -0,0 +1,64 @@ +// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine License +// Agreement. + +#include "string_format.h" + +#include +#include + +#include + +namespace wvutil { + +TEST(StringFormatTest, SignedInteger) { + constexpr char kFormat[] = "Version %d"; + constexpr char kResult[] = "Version -123"; + std::string result; + EXPECT_TRUE(FormatString(&result, kFormat, -123)); + EXPECT_EQ(result, kResult); +} + +TEST(StringFormatTest, UnsignedInteger) { + constexpr char kFormat[] = "Version %u"; + constexpr char kResult[] = "Version 27"; + std::string result; + EXPECT_TRUE(FormatString(&result, kFormat, 27)); + EXPECT_EQ(result, kResult); +} + +TEST(StringFormatTest, HexInteger) { + constexpr char kFormat[] = "Version %X"; + constexpr char kResult[] = "Version FF"; + std::string result; + EXPECT_TRUE(FormatString(&result, kFormat, 0xFF)); + EXPECT_EQ(result, kResult); +} + +TEST(StringFormatTest, Strings) { + constexpr char kFormat[] = "Hello, %s."; + constexpr char kResult[] = "Hello, DRM."; + std::string result; + EXPECT_TRUE(FormatString(&result, kFormat, "DRM")); + EXPECT_EQ(result, kResult); +} + +TEST(StringFormatTest, Nothing) { + constexpr char kString[] = "No format fields."; + std::string result; + EXPECT_TRUE(FormatString(&result, kString)); + EXPECT_EQ(result, kString); +} + +TEST(StringFormatTest, NullOutput) { + constexpr char kString[] = "This will never be referenced."; + EXPECT_FALSE(FormatString(nullptr, kString)); +} + +TEST(StringFormatTest, NullFormat) { + std::string result; + EXPECT_FALSE(FormatString(&result, nullptr)); + EXPECT_TRUE(result.empty()); +} + +} // namespace wvutil