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
This commit is contained in:
John "Juce" Bruce
2022-11-14 21:20:40 -08:00
committed by John Bruce
parent a3e67a9104
commit ff73463d0b
5 changed files with 124 additions and 0 deletions

View File

@@ -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 {

View File

@@ -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 \

View File

@@ -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 <string>
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_

View File

@@ -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 <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory>
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<size_t>(desired_size) + 1; // +1 for null
std::unique_ptr<char[]> 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

View File

@@ -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 <gmock/gmock.h>
#include <gtest/gtest.h>
#include <string>
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