diff --git a/implementation/jni_helper/BUILD b/implementation/jni_helper/BUILD index b81be0c9..9f4b747e 100644 --- a/implementation/jni_helper/BUILD +++ b/implementation/jni_helper/BUILD @@ -7,6 +7,25 @@ licenses(["notice"]) exports_files(["LICENSE"]) +################################################################################ +# ArgPrint. +################################################################################ +cc_library( + name = "arg_string", + hdrs = ["arg_string.h"], + deps = ["//:jni_dep"], +) + +cc_test( + name = "arg_string_test", + srcs = ["arg_string_test.cc"], + deps = [ + ":arg_string", + "//:jni_dep", + "@googletest//:gtest_main", + ], +) + ################################################################################ # FieldValue. ################################################################################ diff --git a/implementation/jni_helper/arg_string.h b/implementation/jni_helper/arg_string.h new file mode 100644 index 00000000..c7eaa577 --- /dev/null +++ b/implementation/jni_helper/arg_string.h @@ -0,0 +1,75 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef JNI_BIND_IMPLEMENTATION_JNI_HELPER_ARG_STRING_H_ +#define JNI_BIND_IMPLEMENTATION_JNI_HELPER_ARG_STRING_H_ + +#include +#include + +namespace jni { + +// A basic default printer that uses `printf`. +template +struct ArgStringify { + static std::string Str(const T& val) { + std::stringstream ss; + ss << val; + + return ss.str(); + } +}; + +template +struct ArgStringify { + static std::string Str(const T* val) { + if (val == nullptr) { + return "nullptr"; + } + + std::stringstream ss; + ss << val; + + return ss.str(); + } +}; + +// Helper function to select correct ArgString partial specialization. +template +std::string ArgString(const T& val) { + return ArgStringify::Str(val); +} + +//////////////////////////////////////////////////////////////////////////////// +// Void. +//////////////////////////////////////////////////////////////////////////////// +template <> +struct ArgStringify { + static std::string Str() { return ""; } +}; + +inline std::string ArgString() { return ArgStringify::Str(); } + +//////////////////////////////////////////////////////////////////////////////// +// Bool. +//////////////////////////////////////////////////////////////////////////////// +template <> +struct ArgStringify { + static std::string Str(const bool val) { return val ? "TRUE" : "FALSE"; } +}; + +} // namespace jni + +#endif // JNI_BIND_IMPLEMENTATION_JNI_HELPER_ARG_STRING_H_ diff --git a/implementation/jni_helper/arg_string_test.cc b/implementation/jni_helper/arg_string_test.cc new file mode 100644 index 00000000..d0a2485d --- /dev/null +++ b/implementation/jni_helper/arg_string_test.cc @@ -0,0 +1,91 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "implementation/jni_helper/arg_string.h" + +#include + +#include +#include "jni_dep.h" + +using ::jni::ArgString; + +namespace { + +//////////////////////////////////////////////////////////////////////////////// +// Void. +//////////////////////////////////////////////////////////////////////////////// +TEST(ArgString, Void) { EXPECT_EQ(ArgString(), ""); } + +//////////////////////////////////////////////////////////////////////////////// +// Primitive Types. +//////////////////////////////////////////////////////////////////////////////// +TEST(ArgString, Bool) { + EXPECT_EQ(ArgString(true), "TRUE"); + EXPECT_EQ(ArgString(false), "FALSE"); +} + +TEST(ArgString, Char) { + EXPECT_EQ(ArgString('x'), "x"); + EXPECT_EQ(ArgString('y'), "y"); + EXPECT_EQ(ArgString('z'), "z"); +} + +TEST(ArgString, Short) { + EXPECT_EQ(ArgString(jshort{32767}), "32767"); + EXPECT_EQ(ArgString(jshort{-32768}), "-32768"); + EXPECT_EQ(ArgString(static_cast(65535)), "-1"); // no unsigned +} + +TEST(ArgString, Int) { EXPECT_EQ(ArgString(jint{-2147483648}), "-2147483648"); } + +TEST(ArgString, Long) { + EXPECT_EQ(ArgString(jlong{9223372036854775807}), "9223372036854775807"); +} + +TEST(ArgString, Float) { + EXPECT_EQ(ArgString(jfloat{std::numeric_limits::max()}), + "3.40282e+38"); +} + +TEST(ArgString, Double) { + EXPECT_EQ(ArgString(jdouble{std::numeric_limits::max()}), + "1.79769e+308"); +} + +//////////////////////////////////////////////////////////////////////////////// +// Pointers. +//////////////////////////////////////////////////////////////////////////////// +TEST(ArgString, HandlesNullPointers) { + EXPECT_EQ(ArgString(reinterpret_cast(0)), "nullptr"); +} + +TEST(ArgString, Pointers) { + EXPECT_EQ(ArgString(reinterpret_cast(0XABCDEF)), "0xabcdef"); +} + +//////////////////////////////////////////////////////////////////////////////// +// Char* (Strings). +//////////////////////////////////////////////////////////////////////////////// +TEST(ArgString, NullForEmptyChar) { + EXPECT_EQ(ArgString(static_cast(nullptr)), "nullptr"); +} + +TEST(ArgString, ExplicitLengthArray) { + EXPECT_EQ(ArgString("fooBaz"), // Type is char[7]. + "fooBaz"); +} + +} // namespace diff --git a/metaprogramming/BUILD b/metaprogramming/BUILD index 3655b7b5..bf610fe8 100644 --- a/metaprogramming/BUILD +++ b/metaprogramming/BUILD @@ -179,6 +179,23 @@ cc_test( ], ) +################################################################################ +# color. +################################################################################ +cc_library( + name = "color", + hdrs = ["color.h"], +) + +cc_test( + name = "color_test", + srcs = ["color_test.cc"], + deps = [ + ":color", + "@googletest//:gtest_main", + ], +) + ################################################################################ # Concatenate. ################################################################################ diff --git a/metaprogramming/color.h b/metaprogramming/color.h new file mode 100644 index 00000000..e6d5edc4 --- /dev/null +++ b/metaprogramming/color.h @@ -0,0 +1,76 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef JNI_BIND_METAPROGRAMMING_COLOUR_H_ +#define JNI_BIND_METAPROGRAMMING_COLOUR_H_ + +#include +#include + +namespace jni::metaprogramming { + +struct Color { + static constexpr std::string_view kNone{"\033[0m"}; + + // --- Text Colors --- + static constexpr std::string_view kBlack = "\033[0;30m"; + static constexpr std::string_view kBlackBold = "\033[1;30m"; + static constexpr std::string_view kRed = "\033[0;31m"; + static constexpr std::string_view kRedBold = "\033[1;31m"; + static constexpr std::string_view kGreen = "\033[0;32m"; + static constexpr std::string_view kGreenBold = "\033[1;32m"; + static constexpr std::string_view kYellow = "\033[0;33m"; + static constexpr std::string_view kYellowBold = "\033[1;33m"; + static constexpr std::string_view kBlue = "\033[0;34m"; + static constexpr std::string_view kBlueBold = "\033[1;34m"; + static constexpr std::string_view kPurple = "\033[0;35m"; + static constexpr std::string_view kPurpleBold = "\033[1;35m"; + static constexpr std::string_view kCyan = "\033[0;36m"; + static constexpr std::string_view kCyanBold = "\033[1;36m"; + static constexpr std::string_view kWhite = "\033[0;37m"; + static constexpr std::string_view kWhiteBold = "\033[1;37m"; + + // --- Background Colors --- + static constexpr std::string_view kBgBlack = "\033[40m"; + static constexpr std::string_view kBgBlackBold = "\033[100m"; + static constexpr std::string_view kBgRed = "\033[41m"; + static constexpr std::string_view kBgRedBold = "\033[101m"; + static constexpr std::string_view kBgGreen = "\033[42m"; + static constexpr std::string_view kBgGreenBold = "\033[102m"; + static constexpr std::string_view kBgYellow = "\033[43m"; + static constexpr std::string_view kBgYellowBold = "\033[103m"; + static constexpr std::string_view kBgBlue = "\033[44m"; + static constexpr std::string_view kBgBlueBold = "\033[104m"; + static constexpr std::string_view kBgPurple = "\033[45m"; + static constexpr std::string_view kBgPurpleBold = "\033[105m"; + static constexpr std::string_view kBgCyan = "\033[46m"; + static constexpr std::string_view kBgCyanBold = "\033[106m"; + static constexpr std::string_view kBgWhite = "\033[47m"; + static constexpr std::string_view kBgWhiteBold = "\033[107m"; +}; + +// Colorize function for runtime manipulation of text. This is suitable when +// the string is unknowable until runtime. +inline std::string Colorize(std::string_view colour, std::string_view str, + bool colourize = true) { + return !colourize ? std::string{str} + : std::string{colour} + std::string{str} + + std::string{Color::kNone}; +} + +} // namespace jni::metaprogramming + +#endif // JNI_BIND_METAPROGRAMMING_COLOUR_H_ diff --git a/metaprogramming/color_test.cc b/metaprogramming/color_test.cc new file mode 100644 index 00000000..9c9fedb9 --- /dev/null +++ b/metaprogramming/color_test.cc @@ -0,0 +1,46 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "color.h" + +#include +#include + +#include + +using ::jni::metaprogramming::Color; +using ::jni::metaprogramming::Colorize; + +namespace { + +TEST(ColorTest, HasBlue) { + std::string output = Colorize(Color::kBlue, "Blue words").data(); + + printf("%s\n", output.c_str()); + + EXPECT_TRUE(Colorize(Color::kBlue, "Blue words").find(Color::kBlue) != + std::string::npos); +} + +TEST(ColorTest, HasGreenAndDoesntBleed) { + std::string output = Colorize(Color::kRed, "Red words").data(); + printf("%s, no color.\n", output.c_str()); + + EXPECT_TRUE(output.find(Color::kRed) != std::string::npos); + EXPECT_TRUE(output.find(Color::kNone) != std::string::npos); +} + +} // namespace